diff --git a/Config.py b/Config.py index c8043fb..462e34a 100644 --- a/Config.py +++ b/Config.py @@ -1,17 +1,18 @@ import json -from Parameters import ARGS +from Parameters import parse class Config(dict): - def __init__(self, init_dict=None, ARGS=ARGS, config_file_name=None): + def __init__(self, init_dict=None, parser=parse, config_file_name=None): """ Takes in command-line arguments as well as the configuration file and parses them. Parameters ----------------- :param init_dict: : a dictionary of configuration settings to use - :param ARGS: : the command-line arguments to take, structured like a dictionary :param config_file_name: : relative filepath to config file """ + + ARGS = parse() if init_dict: self.load_config(init_dict) config_file_name = './configs/' + (config_file_name or (ARGS and ARGS.config) or '') @@ -49,5 +50,3 @@ def load_config(self, kv, ARGS=None): self[key] = Config(init_dict=kv[key], ARGS=ARGS, config_file_name=None) else: self[key] = kv[key] - -config = Config() diff --git a/Parameters.py b/Parameters.py index 44daea5..c24892b 100644 --- a/Parameters.py +++ b/Parameters.py @@ -2,66 +2,69 @@ import argparse # default python library for command line argument parsing import os -parser = argparse.ArgumentParser( # pylint: disable=invalid-name - description='Train DNNs on model car data.', - formatter_class=argparse.ArgumentDefaultsHelpFormatter) +def parse(): + parser = argparse.ArgumentParser( # pylint: disable=invalid-name + description='Train DNNs on model car data.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) -parser.add_argument('--gpu', default=-1, type=int, help='Cuda GPU ID') -parser.add_argument('--epoch', default=0, type=int, help='Cuda GPU ID') -parser.add_argument('--batch-size', default=100, type=int) -parser.add_argument('--display', dest='display', action='store_true') -parser.add_argument('--no-display', dest='display', action='store_false') -parser.set_defaults(display=True) + parser.add_argument('--gpu', default=-1, type=int, help='Cuda GPU ID') + parser.add_argument('--epoch', default=0, type=int, help='Cuda GPU ID') + parser.add_argument('--batch-size', default=100, type=int) + parser.add_argument('--display', dest='display', action='store_true') + parser.add_argument('--no-display', dest='display', action='store_false') + parser.set_defaults(display=True) -parser.add_argument('--verbose', default=True, type=bool, help='Debugging mode') -parser.add_argument('--aruco', default=True, type=bool, help='Use Aruco data') -parser.add_argument('--data-path', default='/hostroot/home/dataset/' + - 'bair_car_data', type=str) -parser.add_argument('--resume-path', default=None, type=str, help='Path to' + - ' resume file containing network state dictionary') -parser.add_argument('--bkup', default=None, type=str, help='Path to' + - ' resume file containing network state dictionary') -parser.add_argument('--save-path', default='save', type=str, help='Path to' + - ' folder to save net state dictionaries.') + parser.add_argument('--verbose', default=True, type=bool, help='Debugging mode') + parser.add_argument('--aruco', default=True, type=bool, help='Use Aruco data') + parser.add_argument('--data-path', default='/hostroot/home/dataset/' + + 'bair_car_data', type=str) + parser.add_argument('--resume-path', default=None, type=str, help='Path to' + + ' resume file containing network state dictionary') + parser.add_argument('--bkup', default=None, type=str, help='Path to' + + ' resume file containing network state dictionary') + parser.add_argument('--save-path', default='save', type=str, help='Path to' + + ' folder to save net state dictionaries.') # nargs='+' allows for multiple arguments and stores arguments in a list -parser.add_argument( - '--ignore', - default=( - 'reject_run', - 'left', - 'out1_in2', - 'play', - 'Smyth', - 'racing'), - type=str, - nargs='+', - help='Skips these labels in data.') + parser.add_argument( + '--ignore', + default=( + 'reject_run', + 'left', + 'out1_in2', + 'play', + 'Smyth', + 'racing'), + type=str, + nargs='+', + help='Skips these labels in data.') -parser.add_argument('--require-one', default=(), type=str, nargs='+', - help='Skips data without these labels in data.') -parser.add_argument('--use-states', default=(1, 3, 5, 6, 7), type=str, - nargs='+', help='Skips data outside of these states.') + parser.add_argument('--require-one', default=(), type=str, nargs='+', + help='Skips data without these labels in data.') + parser.add_argument('--use-states', default=(1, 3, 5, 6, 7), type=str, + nargs='+', help='Skips data outside of these states.') -parser.add_argument('--nframes', default=8, type=int, - help='# timesteps of camera input') -parser.add_argument('--nsteps', default=10, type=int, - help='# of steps of time to predict in the future') -parser.add_argument('--stride', default=10, type=int, - help="number of timesteps between network predictions") -parser.add_argument('--log-interval', default=1, type=int, - help="Number of batches in between logging") + parser.add_argument('--nframes', default=8, type=int, + help='# timesteps of camera input') + parser.add_argument('--nsteps', default=10, type=int, + help='# of steps of time to predict in the future') + parser.add_argument('--stride', default=10, type=int, + help="number of timesteps between network predictions") + parser.add_argument('--log-interval', default=1, type=int, + help="Number of batches in between logging") -parser.add_argument('--print-moments', default=1000, type=int, - help='# of moments between printing stats') -parser.add_argument('--save-moments', default=400000, type=int, - help='# of moments between printing stats') + parser.add_argument('--print-moments', default=1000, type=int, + help='# of moments between printing stats') + parser.add_argument('--save-moments', default=400000, type=int, + help='# of moments between printing stats') -parser.add_argument('--config', default='default.json', type=str, help='Path of config file to use in ' + - 'experiment from ./configs') + parser.add_argument('--config', default='default.json', type=str, help='Path of config file to use in ' + + 'experiment from ./configs') -ARGS = parser.parse_args() + ARGS = parser.parse_args() # Check for $DISPLAY being blank -if 'DISPLAY' not in os.environ: - ARGS.display = False + if 'DISPLAY' not in os.environ: + ARGS.display = False + + return ARGS diff --git a/Train.py b/Train.py index 7b57c97..9127558 100644 --- a/Train.py +++ b/Train.py @@ -6,7 +6,8 @@ import os import importlib -from Config import config +from Config import Config + from Dataset import Dataset import Utils @@ -14,11 +15,9 @@ from torch.autograd import Variable import torch.nn.utils as nnutils import torch -Net = importlib.import_module(config['model']['py_path']).Net def iterate(net, loss_func, optimizer=None, input=None, truth=None, mask=None, train=True): - """ - Encapsulates a training or validation iteration. + """Encapsulates a training or validation iteration. :param net: : network to train :param optimizer: : optimizer to use @@ -52,6 +51,8 @@ def iterate(net, loss_func, optimizer=None, input=None, truth=None, mask=None, t return loss.cpu().data[0] def main(): + """Main training loop""" + # Configure logging logging.basicConfig(filename=config['logging']['path'], level=logging.DEBUG) logging.debug(config) @@ -169,4 +170,6 @@ def main(): sys.exit(1) if __name__ == '__main__': + config = Config() + Net = importlib.import_module(config['model']['py_path']).Net main() diff --git a/Utils.py b/Utils.py index 8fed947..18d9e21 100644 --- a/Utils.py +++ b/Utils.py @@ -2,7 +2,6 @@ import os import operator import time -from Parameters import ARGS import matplotlib.pyplot as plt import numpy as np import torch diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..009455b --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = BDDModelCarTraining +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle new file mode 100644 index 0000000..044700c Binary files /dev/null and b/docs/_build/doctrees/environment.pickle differ diff --git a/docs/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree new file mode 100644 index 0000000..52e177e Binary files /dev/null and b/docs/_build/doctrees/index.doctree differ diff --git a/docs/_build/doctrees/source/modules.doctree b/docs/_build/doctrees/source/modules.doctree new file mode 100644 index 0000000..e0ca5bf Binary files /dev/null and b/docs/_build/doctrees/source/modules.doctree differ diff --git a/docs/_build/doctrees/source/training.doctree b/docs/_build/doctrees/source/training.doctree new file mode 100644 index 0000000..0313700 Binary files /dev/null and b/docs/_build/doctrees/source/training.doctree differ diff --git a/docs/_build/doctrees/source/training.nets.doctree b/docs/_build/doctrees/source/training.nets.doctree new file mode 100644 index 0000000..6083459 Binary files /dev/null and b/docs/_build/doctrees/source/training.nets.doctree differ diff --git a/docs/_build/doctrees/source/training.nets.eric.doctree b/docs/_build/doctrees/source/training.nets.eric.doctree new file mode 100644 index 0000000..626be2e Binary files /dev/null and b/docs/_build/doctrees/source/training.nets.eric.doctree differ diff --git a/docs/_build/doctrees/source/training.nets.eric.nonsqueeze.doctree b/docs/_build/doctrees/source/training.nets.eric.nonsqueeze.doctree new file mode 100644 index 0000000..674abd2 Binary files /dev/null and b/docs/_build/doctrees/source/training.nets.eric.nonsqueeze.doctree differ diff --git a/docs/_build/doctrees/source/training.nets.eric.smallmodels.doctree b/docs/_build/doctrees/source/training.nets.eric.smallmodels.doctree new file mode 100644 index 0000000..66d686b Binary files /dev/null and b/docs/_build/doctrees/source/training.nets.eric.smallmodels.doctree differ diff --git a/docs/_build/doctrees/source/training.nets.eric.tinymodels.doctree b/docs/_build/doctrees/source/training.nets.eric.tinymodels.doctree new file mode 100644 index 0000000..9b04045 Binary files /dev/null and b/docs/_build/doctrees/source/training.nets.eric.tinymodels.doctree differ diff --git a/docs/_build/doctrees/wiki/TX2.doctree b/docs/_build/doctrees/wiki/TX2.doctree new file mode 100644 index 0000000..0fec807 Binary files /dev/null and b/docs/_build/doctrees/wiki/TX2.doctree differ diff --git a/docs/_build/doctrees/wiki/computermonitor.doctree b/docs/_build/doctrees/wiki/computermonitor.doctree new file mode 100644 index 0000000..5831b4e Binary files /dev/null and b/docs/_build/doctrees/wiki/computermonitor.doctree differ diff --git a/docs/_build/doctrees/wiki/computersetup.doctree b/docs/_build/doctrees/wiki/computersetup.doctree new file mode 100644 index 0000000..b502160 Binary files /dev/null and b/docs/_build/doctrees/wiki/computersetup.doctree differ diff --git a/docs/_build/doctrees/wiki/dataset.doctree b/docs/_build/doctrees/wiki/dataset.doctree new file mode 100644 index 0000000..48bc386 Binary files /dev/null and b/docs/_build/doctrees/wiki/dataset.doctree differ diff --git a/docs/_build/html/.buildinfo b/docs/_build/html/.buildinfo new file mode 100644 index 0000000..654fbbe --- /dev/null +++ b/docs/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: e75c1114160e13dcb17c687f7c4ed2cf +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/_build/html/.nojekyll b/docs/_build/html/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/_build/html/_modules/index.html b/docs/_build/html/_modules/index.html new file mode 100644 index 0000000..4ed7b61 --- /dev/null +++ b/docs/_build/html/_modules/index.html @@ -0,0 +1,244 @@ + + + + + + + + + + + Overview: module code — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/ArucoDataset.html b/docs/_build/html/_modules/training/ArucoDataset.html new file mode 100644 index 0000000..517a096 --- /dev/null +++ b/docs/_build/html/_modules/training/ArucoDataset.html @@ -0,0 +1,418 @@ + + + + + + + + + + + training.ArucoDataset — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.ArucoDataset
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.ArucoDataset

+import numpy as np
+import time
+import h5py
+import torch
+import torch.utils.data as data
+import sys
+from random import shuffle
+import os
+import matplotlib.pyplot as plt
+
+
+
[docs]class ArucoDataset(data.Dataset): + def __init__(self, data_folder_dir, require_one, ignore_list, stride=10, max_len=-1): + self.max_len = max_len + self.runs = os.walk(os.path.join(data_folder_dir, 'processed_h5py')).next()[1] + shuffle(self.runs) # shuffle each epoch to allow shuffle False + self.run_files = [] + + # Initialize List of Files + self.invisible = [] + self.visible = [] + self.total_length = 0 + self.full_length = 0 + + run_num = 0 + for run in self.runs: + run_num += 1 + segs_in_run = os.walk(os.path.join(data_folder_dir, 'processed_h5py', run)).next()[1] + shuffle(segs_in_run) # shuffle on each epoch to allow shuffle False + + run_labels = h5py.File( + os.path.join(data_folder_dir, + 'processed_h5py', + run, + 'run_labels.h5py'), + 'r') + + # Ignore invalid runs + ignored = False + for ignore in ignore_list: + if ignore in run_labels and run_labels[ignore][0]: + ignored = True + break + if ignored: + continue + + ignored = len(require_one) > 0 + for require in require_one: + if require in run_labels and run_labels[require][0]: + ignored = False + break + if ignored: + continue + + print 'Loading Run {}/{}'.format(run_num, len(self.runs)) + for seg in segs_in_run: + images = h5py.File( + os.path.join( + data_folder_dir, + 'processed_h5py', + run, + seg, + 'images.h5py'), + 'r') + + metadata = h5py.File( + os.path.join(data_folder_dir, + 'processed_h5py', + run, + seg, + 'metadata.h5py'), + 'r') + + + length = len(images['left']) + self.run_files.append({'images': images, 'metadata': metadata, 'run_labels' : run_labels}) + + self.visible.append(self.total_length) # visible indicies + + # invisible is not actually used at all, but is extremely useful + # for debugging indexing problems and gives very little slowdown + self.invisible.append(self.full_length + 7) # actual indicies mapped + + self.total_length += 4 * (length - 7) + self.full_length += length + + # Create row gradient + self.row_gradient = torch.FloatTensor(94, 168) + for row in range(94): + self.row_gradient[row, :] = row / 93. + + # Create col gradient + self.col_gradient = torch.FloatTensor(94, 168) + for col in range(168): + self.col_gradient[:, col] = col / 167. + + self.stride = stride + self.aruco_idx_to_key = ['cwdirect', 'ccwdirect', 'cwfollow', 'ccwfollow'] + + def __getitem__(self, index): + run_idx, t = self.create_map(index) + camera_t = t // 4 + aruco_idx = t % 4 + aruco_key = self.aruco_idx_to_key[aruco_idx] + + list_camera_input = [] + + list_camera_input.append( + torch.from_numpy( + self.run_files[ + run_idx]['images']['left'][camera_t - 7])) + + for delta_time in range(6, -1, -1): + list_camera_input.append( + torch.from_numpy( + self.run_files[ + run_idx]['images']['left'][camera_t - delta_time,:,:,1:2])) + + list_camera_input.append( + torch.from_numpy( + self.run_files[ + run_idx]['images']['right'][camera_t - 1,:,:,1:2])) + + list_camera_input.append( + torch.from_numpy( + self.run_files[ + run_idx]['images']['right'][camera_t,:,:,1:2])) + + camera_data = torch.cat(list_camera_input, 2) + camera_data = camera_data.float() / 255. - 0.5 + camera_data = torch.transpose(camera_data, 0, 2) + camera_data = torch.transpose(camera_data, 1, 2) + + final_camera_data = torch.FloatTensor(14, 94, 168) + final_camera_data[0:12, :, :] = camera_data + final_camera_data[12, :, :] = self.row_gradient + final_camera_data[13, :, :] = self.col_gradient + + # Get behavioral mode + metadata_raw = self.run_files[run_idx]['run_labels'] + metadata = torch.FloatTensor(20, 11, 20) + metadata[:] = 0. + + if aruco_idx < 2: # Direct + metadata[2, :, :] = 1. + else: # Follow + metadata[1, :, :] = 1. + if aruco_idx % 2 == 0: # Clockwise + metadata[5, :, :] = 1. + else: # Counterclockwise + metadata[6, :, :] = 1. + + # Get Ground Truth + steer = [] + motor = [] + + steer.append(float(self.run_files[run_idx]['metadata'][aruco_key][0])) + for i in range(0, self.stride * 9, self.stride): + steer.append(0.) + + motor.append(float(self.run_files[run_idx]['metadata']['motor'][0])) + for i in range(0, self.stride * 29, self.stride): + motor.append(0.) + + final_ground_truth = torch.FloatTensor(steer + motor) / 99. + + mask = torch.FloatTensor([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, # ONLY VALIDATE ON ONE STEERING AND MOTOR + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + + return final_camera_data, metadata, final_ground_truth, mask + + def __len__(self): + if self.max_len == -1: + return self.total_length + return min(self.total_length, self.max_len) + +
[docs] def create_map(self, global_index): + for idx, length in enumerate(self.visible[::-1]): + if global_index >= length: + return len(self.visible) - idx - 1, global_index - length + 7
+ +if __name__ == '__main__': + train_dataset = Dataset('/hostroot/data/dataset/bair_car_data_new_28April2017', [], []) + train_data_loader = torch.utils.data.DataLoader(train_dataset, + batch_size=500, + shuffle=False, pin_memory=False) + start = time.time() + for cam, meta, truth, mask in train_data_loader: + cur = time.time() + print(500./(cur - start)) + start = cur + pass +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/Config.html b/docs/_build/html/_modules/training/Config.html new file mode 100644 index 0000000..31d2eb3 --- /dev/null +++ b/docs/_build/html/_modules/training/Config.html @@ -0,0 +1,276 @@ + + + + + + + + + + + training.Config — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for training.Config

+import json
+from Parameters import parse
+
+
[docs]class Config(dict): + def __init__(self, init_dict=None, parser=parse, config_file_name=None): + """ + Takes in command-line arguments as well as the configuration file and parses them. + + Parameters + ----------------- + :param init_dict: <dict>: a dictionary of configuration settings to use + :param config_file_name: <str>: relative filepath to config file + """ + + ARGS = parse() + if init_dict: + self.load_config(init_dict) + config_file_name = './configs/' + (config_file_name or (ARGS and ARGS.config) or '') + config_file_name = config_file_name.replace('configs/configs', 'configs') + if ARGS: + ARGS.config = '' + if config_file_name != './configs/': + self.load_helper(config_file_name, ARGS) + +
[docs] def load_helper(self, path=None, ARGS=None): + if path is None: + base_config = json.load(open('./configs/default.json', 'r')) + self.load_config(base_config) + else: + config_dict = json.load(open(path, 'r')) + if config_dict['parent_config']: + self.load_helper(('./configs/' + config_dict['parent_config']) + .replace('./configs/configs/', './configs/')) + self.load_config(config_dict, ARGS)
+ +
[docs] def load_config(self, kv, ARGS=None): + """ + Loads in a configuration from a dictionary + + :param kv: <key-val>: a key-val data structure + :return: None + """ + for key in kv: + if key == 'gpu' and ARGS and ARGS.gpu != -1: + self['gpu'] = ARGS + if type(kv[key]) is dict: + if key in self: + self[key].load_config(kv[key]) + else: + self[key] = Config(init_dict=kv[key], ARGS=ARGS, config_file_name=None) + else: + self[key] = kv[key]
+
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/Dataset.html b/docs/_build/html/_modules/training/Dataset.html new file mode 100644 index 0000000..0f5cd2b --- /dev/null +++ b/docs/_build/html/_modules/training/Dataset.html @@ -0,0 +1,457 @@ + + + + + + + + + + + training.Dataset — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for training.Dataset

+import numpy as np
+import time
+import h5py
+import torch
+import torch.utils.data as data
+import sys
+from random import shuffle
+import os
+import matplotlib.pyplot as plt
+from random import shuffle
+import random
+
+
+
+
[docs]class Dataset(data.Dataset): + + def __init__(self, data_folder_dir, require_one=[], ignore_list=[], stride=10, max_len=-1, + train_ratio=0.9, seed=None, nframes=2, nsteps=10, separate_frames=False, + metadata_shape=[], p_exclude_run=0.): + self.max_len = max_len + self.runs = os.walk(os.path.join(data_folder_dir, 'processed_h5py'), followlinks=True).next()[1] + self.run_files = [] + + # Initialize List of Files + self.invisible = [] + self.visible = [] + self.total_length = 0 + self.full_length = 0 + + self.train_part = None + self.val_part = None + + self.separate_frames = separate_frames + + self.train_ratio = train_ratio + + self.nframes = nframes + self.nsteps = nsteps + + self.metadata_shape = metadata_shape + + random.seed(seed * 2) + + for run in self.runs: + segs_in_run = os.walk(os.path.join(data_folder_dir, 'processed_h5py', run), followlinks=True).next()[1] + + run_labels = None + try: + run_labels = h5py.File( + os.path.join(data_folder_dir, 'processed_h5py', run, 'run_labels.h5py'), + 'r') + except Exception: + continue + + if random.random() < p_exclude_run: + continue + + # Ignore invalid runs + ignored = False + for ignore in ignore_list: + if ignore in run_labels and run_labels[ignore][0]: + ignored = True + break + if ignored: + continue + + ignored = len(require_one) > 0 + for require in require_one: + if require in run_labels and run_labels[require][0]: + ignored = False + break + if ignored: + continue + + print 'Loading Run ' + run + for seg in segs_in_run: + images = h5py.File( + os.path.join( + data_folder_dir, + 'processed_h5py', + run, + seg, + 'images.h5py'), + 'r') + + metadata = h5py.File( + os.path.join(data_folder_dir, + 'processed_h5py', + run, + seg, + 'metadata.h5py'), + 'r') + + length = len(images['left']) + + self.run_files.append({'images': images, 'metadata': metadata, 'run_labels' : run_labels}) + self.visible.append(self.total_length) # visible indicies + + # invisible is not actually used at all, but is extremely useful + # for debugging indexing problems and gives very little slowdown + self.invisible.append(self.full_length + 7) # actual indicies mapped + + self.total_length += (length - (self.nsteps * stride - 1) - 7) + self.full_length += length + + # Create row gradient + self.row_gradient = torch.FloatTensor(94, 168) + for row in range(94): + self.row_gradient[row, :] = row / 93. + + # Create col gradient + self.col_gradient = torch.FloatTensor(94, 168) + for col in range(168): + self.col_gradient[:, col] = col / 167. + + self.stride = stride + + self.seed = seed or self.total_length + self.subsampled_train_part = None + + def __getitem__(self, index): + run_idx, t = self.create_map(index) + + data_file = self.run_files[run_idx]['images'] + metadata_file = self.run_files[run_idx]['metadata'] + + list_camera_input = [] + + for t in range(self.nframes): + for camera in ('left', 'right'): + list_camera_input.append(torch.from_numpy(data_file[camera][t])) + camera_data = torch.cat(list_camera_input, 2) + camera_data = camera_data.cuda().float() / 255. - 0.5 + camera_data = torch.transpose(camera_data, 0, 2) + camera_data = torch.transpose(camera_data, 1, 2) + + # Get behavioral mode + metadata_raw = self.run_files[run_idx]['run_labels'] + + metadata = torch.FloatTensor(self.nframes, 64, 23, 41) + metadata = torch.FloatTensor(*self.metadata_shape) + + metadata[:] = 0. + for label_idx, cur_label in enumerate(['racing', 'follow', 'direct', 'play', 'furtive', 'clockwise', 'counterclockwise']): + if self.separate_frames: + metadata[:, label_idx, :, :] = int(cur_label in metadata_raw and metadata_raw[cur_label][0]) + else: + metadata[label_idx, :, :] = int(cur_label in metadata_raw and metadata_raw[cur_label][0]) + + # Get Ground Truth + steer = [] + motor = [] + + for i in range(0, self.stride * self.nsteps, self.stride): + steer.append(float(self.run_files[run_idx]['metadata']['steer'][t + i])) + for i in range(0, self.stride * self.nsteps, self.stride): + motor.append(float(self.run_files[run_idx]['metadata']['motor'][t + i])) + for i in range(0, self.stride * self.nsteps * 2, self.stride): + motor.append(0.) + + final_ground_truth = torch.FloatTensor(steer + motor) / 99. + + mask = torch.FloatTensor([1] * (2 * self.nsteps) + # use all data + [0] * (2 * self.nsteps)) # no mask + + return camera_data, metadata, final_ground_truth, mask + + def __len__(self): + if self.max_len == -1: + return self.total_length + return min(self.total_length, self.max_len) + +
[docs] def train_len(self): + return len(self.train_part)
+ +
[docs] def val_len(self): + return len(self.val_part)
+ +
[docs] def get_train_partition(self): + if self.train_part: + return self.train_part + else: + self.train_part = set() + self.val_part = set() + random.seed(self.seed) + for i in range(len(self)): + if random.random() < self.train_ratio: + self.train_part.add(i) + else: + self.val_part.add(i) + return self.train_part
+ +
[docs] def get_val_partition(self): + if self.val_part: + return self.val_part + else: + self.get_train_partition() + return self.val_part
+ +
[docs] def get_train_loader(self, p_subsample=None, seed=None, *args, **kwargs): + random.seed(seed) + remove_train, train_part = set(), set(self.train_part or self.get_train_partition()) + for i in train_part: + if random.random() > p_subsample: + remove_train.add(i) + for i in remove_train: + train_part.remove(i) + + self.subsampled_train_part = train_part + + kwargs['sampler'] = torch.utils.data.sampler.SubsetRandomSampler(list(train_part)) + return torch.utils.data.DataLoader(self, *args, **kwargs)
+ +
[docs] def get_val_loader(self, *args, **kwargs): + kwargs['sampler'] = torch.utils.data.sampler.SubsetRandomSampler(list(self.get_val_partition())) + return torch.utils.data.DataLoader(self, *args, **kwargs)
+ +
[docs] def create_map(self, global_index): + for idx, length in enumerate(self.visible[::-1]): + if global_index >= length: + return len(self.visible) - idx - 1, global_index - length + 7
+ +if __name__ == '__main__': + train_dataset = Dataset('/hostroot/data/dataset/bair_car_data_Main_Dataset', ['furtive'], []) + train_data_loader = torch.utils.data.DataLoader(train_dataset, + batch_size=500, + shuffle=False, pin_memory=False) + start = time.time() + for cam, meta, truth, mask in train_data_loader: + cur = time.time() + print(500./(cur - start)) + start = cur + pass +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/Parameters.html b/docs/_build/html/_modules/training/Parameters.html new file mode 100644 index 0000000..afacef2 --- /dev/null +++ b/docs/_build/html/_modules/training/Parameters.html @@ -0,0 +1,294 @@ + + + + + + + + + + + training.Parameters — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for training.Parameters

+"""Command line arguments parser configuration."""
+import argparse  # default python library for command line argument parsing
+import os
+
+
[docs]def parse(): + parser = argparse.ArgumentParser( # pylint: disable=invalid-name + description='Train DNNs on model car data.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument('--gpu', default=-1, type=int, help='Cuda GPU ID') + parser.add_argument('--epoch', default=0, type=int, help='Cuda GPU ID') + parser.add_argument('--batch-size', default=100, type=int) + parser.add_argument('--display', dest='display', action='store_true') + parser.add_argument('--no-display', dest='display', action='store_false') + parser.set_defaults(display=True) + + parser.add_argument('--verbose', default=True, type=bool, help='Debugging mode') + parser.add_argument('--aruco', default=True, type=bool, help='Use Aruco data') + parser.add_argument('--data-path', default='/hostroot/home/dataset/' + + 'bair_car_data', type=str) + parser.add_argument('--resume-path', default=None, type=str, help='Path to' + + ' resume file containing network state dictionary') + parser.add_argument('--bkup', default=None, type=str, help='Path to' + + ' resume file containing network state dictionary') + parser.add_argument('--save-path', default='save', type=str, help='Path to' + + ' folder to save net state dictionaries.') + +# nargs='+' allows for multiple arguments and stores arguments in a list + parser.add_argument( + '--ignore', + default=( + 'reject_run', + 'left', + 'out1_in2', + 'play', + 'Smyth', + 'racing'), + type=str, + nargs='+', + help='Skips these labels in data.') + + parser.add_argument('--require-one', default=(), type=str, nargs='+', + help='Skips data without these labels in data.') + parser.add_argument('--use-states', default=(1, 3, 5, 6, 7), type=str, + nargs='+', help='Skips data outside of these states.') + + parser.add_argument('--nframes', default=8, type=int, + help='# timesteps of camera input') + parser.add_argument('--nsteps', default=10, type=int, + help='# of steps of time to predict in the future') + parser.add_argument('--stride', default=10, type=int, + help="number of timesteps between network predictions") + parser.add_argument('--log-interval', default=1, type=int, + help="Number of batches in between logging") + + parser.add_argument('--print-moments', default=1000, type=int, + help='# of moments between printing stats') + parser.add_argument('--save-moments', default=400000, type=int, + help='# of moments between printing stats') + + parser.add_argument('--config', default='default.json', type=str, help='Path of config file to use in ' + + 'experiment from ./configs') + + ARGS = parser.parse_args() + +# Check for $DISPLAY being blank + if 'DISPLAY' not in os.environ: + ARGS.display = False + + return ARGS
+
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/Train.html b/docs/_build/html/_modules/training/Train.html new file mode 100644 index 0000000..3db2488 --- /dev/null +++ b/docs/_build/html/_modules/training/Train.html @@ -0,0 +1,399 @@ + + + + + + + + + + + training.Train — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for training.Train

+"""Training and validation code for bddmodelcar."""
+import sys
+import traceback
+import logging
+import time
+import os
+import importlib
+
+from Config import Config
+
+from Dataset import Dataset
+
+import Utils
+
+from torch.autograd import Variable
+import torch.nn.utils as nnutils
+import torch
+
+
[docs]def iterate(net, loss_func, optimizer=None, input=None, truth=None, mask=None, train=True): + """Encapsulates a training or validation iteration. + + :param net: <nn.Module>: network to train + :param optimizer: <torch.optim>: optimizer to use + :param input: <tuple>: tuple of np.array or tensors to pass into net. Should contain data for this iteration + :param truth: <np.array | tensor>: tuple of np.array to pass into optimizer. Should contain data for this iteration + :param mask: <np.array | tensor>: mask to ignore unnecessary outputs. + :return: loss + """ + + if train: + net.train() + optimizer.zero_grad() + else: + net.eval() + + # Transform inputs into Variables for pytorch and run forward prop + input = tuple([Variable(tensor) for tensor in input]) + outputs = net(*input).cuda() * Variable(mask) + loss = loss_func(outputs, Variable(truth)) + + if not train: + return loss.cpu().data[0] + + # Run backprop, gradient clipping + loss.backward() + nnutils.clip_grad_norm(net.parameters(), 1.0) + + # Apply backprop gradients + optimizer.step() + + return loss.cpu().data[0]
+ +
[docs]def main(): + """Main training loop""" + + # Configure logging + logging.basicConfig(filename=config['logging']['path'], level=logging.DEBUG) + logging.debug(config) + + # Set Up PyTorch Environment + # torch.set_default_tensor_type('torch.FloatTensor') + torch.cuda.set_device(config['hardware']['gpu']) + torch.cuda.device(config['hardware']['gpu']) + + # Define basic training and network parameters + net, loss_func = Net(n_steps=config['model']['future_frames'], + n_frames=config['model']['past_frames']).cuda(), \ + torch.nn.MSELoss().cuda() + + # Iterate over all epochs + for epoch in range(config['training']['start_epoch'], config['training']['num_epochs']): + try: + torch.cuda.set_device(config['hardware']['gpu']) + torch.cuda.device(config['hardware']['gpu']) + if not epoch == 0: + print("Resuming") + save_data = torch.load(os.path.join(config['model']['save_path'], config['model']['name'] + "epoch%02d.weights" % (epoch - 1,))) + net.load_state_dict(save_data) + + net.cuda() + + optimizer = torch.optim.Adam(net.parameters()) + + logging.debug('Starting training epoch #{}'.format(epoch)) + + train_dataset = Dataset(config['training']['dataset']['path'], + require_one=config['dataset']['include_labels'], + ignore_list=config['dataset']['ignore_labels'], + stride=config['model']['frame_stride'], + seed=config['training']['rand_seed'], + nframes=config['model']['past_frames'], + nsteps=config['model']['future_frames'], + train_ratio=config['training']['dataset']['train_ratio'], + separate_frames=config['model']['separate_frames'], + metadata_shape=config['model']['metadata_shape'], + p_exclude_run=config['training']['p_exclude_run']) + + train_data_loader = train_dataset.get_train_loader(batch_size=config['training']['dataset']['batch_size'], + shuffle=config['training']['dataset']['shuffle'], + p_subsample=config['training']['dataset']['p_subsample'], + seed=(epoch+config['training']['rand_seed']), + pin_memory=False) + + train_loss = Utils.LossLog() + start = time.time() + + for batch_idx, (camera, meta, truth, mask) in enumerate(train_data_loader): + # Cuda everything + camera, meta, truth, mask = camera.cuda(), meta.cuda(), truth.cuda(), mask.cuda() + truth = truth * mask + + loss = iterate(net, loss_func=loss_func, optimizer=optimizer, + input=(camera, meta), truth=truth, mask=mask) + + # Logging Loss + train_loss.add(loss) + + print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( + epoch, batch_idx * len(camera), len(train_data_loader.dataset.subsampled_train_part), + 100. * batch_idx / len(train_data_loader), loss)) + + cur = time.time() + print('{} Hz'.format(float(len(camera))/(cur - start))) + start = cur + + + Utils.csvwrite(config['logging']['training_loss'], [train_loss.average()]) + + logging.debug('Finished training epoch #{}'.format(epoch)) + logging.debug('Starting validation epoch #{}'.format(epoch)) + + val_dataset = Dataset(config['validation']['dataset']['path'], + require_one=config['dataset']['include_labels'], + ignore_list=config['dataset']['ignore_labels'], + stride=config['model']['frame_stride'], + seed=config['validation']['rand_seed'], + nframes=config['model']['past_frames'], + train_ratio=config['validation']['dataset']['train_ratio'], + nsteps=config['model']['future_frames'], + separate_frames=config['model']['separate_frames'], + metadata_shape=config['model']['metadata_shape']) + + val_data_loader = val_dataset.get_val_loader(batch_size=config['validation']['dataset']['batch_size'], + shuffle=config['validation']['dataset']['shuffle'], + pin_memory=False) + val_loss = Utils.LossLog() + + net.eval() + + for batch_idx, (camera, meta, truth, mask) in enumerate(val_data_loader): + # Cuda everything + camera, meta, truth, mask = camera.cuda(), meta.cuda(), truth.cuda(), mask.cuda() + truth = truth * mask + + loss = iterate(net, loss_func=loss_func, truth=truth, input=(camera, meta), mask=mask, train=False) + + # Logging Loss + val_loss.add(loss) + + print('Val Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}' + .format(epoch, batch_idx * len(camera), len(val_data_loader.dataset.val_part), + 100. * batch_idx / len(val_data_loader), loss)) + + Utils.csvwrite(config['logging']['validation_loss'], [val_loss.average()]) + logging.debug('Finished validation epoch #{}'.format(epoch)) + Utils.save_net(config['model']['save_path'], config['model']['name'] + "epoch%02d" % (epoch,), net) + + except Exception: + logging.error(traceback.format_exc()) # Log exception + sys.exit(1)
+ +if __name__ == '__main__': + config = Config() + Net = importlib.import_module(config['model']['py_path']).Net + main() +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/Utils.html b/docs/_build/html/_modules/training/Utils.html new file mode 100644 index 0000000..3cea3de --- /dev/null +++ b/docs/_build/html/_modules/training/Utils.html @@ -0,0 +1,302 @@ + + + + + + + + + + + training.Utils — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for training.Utils

+"""Utility classes for training."""
+import os
+import operator
+import time
+import matplotlib.pyplot as plt
+import numpy as np
+import torch
+
+
+
[docs]class MomentCounter: + """Notify after N Data Moments Passed""" + + def __init__(self, n): + self.start = 0 + self.n = n + +
[docs] def step(self, data_index): + if data_index.ctr - self.start >= self.n: + self.start = data_index.ctr + return True + return False
+ + +
[docs]def csvwrite(filename, objs): + with open(filename, 'a') as csvfile: + csvfile.write(",".join([str(x) for x in objs]) +'\n')
+ + +
[docs]class LossLog: + """Keep Track of Loss, can be used within epoch or for per epoch.""" + + def __init__(self): + self.ctr = 0 + self.total_loss = 0 + +
[docs] def add(self, loss): + self.total_loss += loss + self.ctr += 1
+ +
[docs] def average(self): + return self.total_loss / (self.ctr * 1.)
+ +
[docs]def save_net(save_path, save_name, net): + torch.save( + net.state_dict(), + os.path.join( + save_path + save_name + + '.weights')) + + # Next, save for inference (creates ['net'] and moves net to GPU #0) + weights = {'net': net.state_dict().copy()} + for key in weights['net']: + weights['net'][key] = weights['net'][key].cuda(device=0) + torch.save(weights, + os.path.join(save_path + save_name + '.infer'))
+ + +
[docs]def display_sort_data_moment_loss(data_moment_loss_record, data): + sorted_data_moment_loss_record = sorted(data_moment_loss_record.items(), + key=operator.itemgetter(1)) + low_loss_range = range(20) + high_loss_range = range(-1, -20, -1) + + for i in low_loss_range + high_loss_range: + l = sorted_data_moment_loss_record[i] + run_code, seg_num, offset = sorted_data_moment_loss_record[i][0][0] + t = sorted_data_moment_loss_record[i][0][1] + o = sorted_data_moment_loss_record[i][0][2] + + sorted_data = data.get_data(run_code, seg_num, offset) + plt.figure(22) + plt.clf() + plt.ylim(0, 1) + plt.plot(t, 'r.') + plt.plot(o, 'g.') + plt.plot([0, 20], [0.5, 0.5], 'k') + mi(sorted_data['right'][0, :, :], 23, img_title=d2s(l[1])) + plt.pause(1)
+
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/SqueezeNet.html b/docs/_build/html/_modules/training/nets/SqueezeNet.html new file mode 100644 index 0000000..db2a842 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/SqueezeNet.html @@ -0,0 +1,319 @@ + + + + + + + + + + + training.nets.SqueezeNet — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.SqueezeNet
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.SqueezeNet

+"""SqueezeNet 1.1 modified for regression."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+import logging
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+
[docs]class Fire(nn.Module): + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, x): + x = self.squeeze_activation(self.squeeze(x)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(x)), + self.expand3x3_activation(self.expand3x3(x)) + ], 1)
+ + +
[docs]class SqueezeNet(nn.Module): + + def __init__(self, n_steps=10, n_frames=2): + super(SqueezeNet, self).__init__() + + self.n_steps = n_steps + self.n_frames = n_frames + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 64, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(64, 16, 64, 64) + ) + self.post_metadata_features = nn.Sequential( + Fire(256, 16, 64, 64), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(128, 32, 128, 128), + Fire(256, 32, 128, 128), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(256, 48, 192, 192), + Fire(384, 48, 192, 192), + Fire(384, 64, 256, 256), + Fire(512, 64, 256, 256), + ) + final_conv = nn.Conv2d(512, self.n_steps * 4, kernel_size=1) + self.final_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + # nn.ReLU(inplace=True), + nn.AvgPool2d(kernel_size=5, stride=6) + ) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + if m is final_conv: + init.normal(m.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(m.weight.data) + if m.bias is not None: + m.bias.data.zero_() + +
[docs] def forward(self, x, metadata): + x = self.pre_metadata_features(x) + x = torch.cat((x, metadata), 1) + x = self.post_metadata_features(x) + x = self.final_output(x) + x = x.view(x.size(0), -1) + return x
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + test_net = SqueezeNet(20, 6) + a = test_net(Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 128, 23, 41))) + logging.debug('Net Test Output = {}'.format(a)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNet +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/SqueezeNetAruco1.html b/docs/_build/html/_modules/training/nets/SqueezeNetAruco1.html new file mode 100644 index 0000000..119c4d8 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/SqueezeNetAruco1.html @@ -0,0 +1,318 @@ + + + + + + + + + + + training.nets.SqueezeNetAruco1 — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.SqueezeNetAruco1
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.SqueezeNetAruco1

+"""SqueezeNet 1.1 modified for Aruco markers."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+
+
+
[docs]class Fire(nn.Module): + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, x): + x = self.squeeze_activation(self.squeeze(x)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(x)), + self.expand3x3_activation(self.expand3x3(x)) + ], 1)
+ + +
[docs]class SqueezeNet(nn.Module): + + def __init__(self): + super(SqueezeNet, self).__init__() + + self.lr = 0.01 + self.momentum = 0.01 + self.N_FRAMES = 2 + self.N_STEPS = 10 + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(12, 64, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(64, 16, 64, 64), + ) + self.post_metadata_features = nn.Sequential( + Fire(256, 16, 64, 64), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(128, 32, 128, 128), + Fire(256, 32, 128, 128), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(256, 48, 192, 192), + Fire(384, 48, 192, 192), + Fire(384, 64, 256, 256), + Fire(512, 64, 256, 256), + ) + final_conv = nn.Conv2d(512, 66, kernel_size=1) + self.final_output_Aruco = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + # nn.ReLU(inplace=True), + nn.AvgPool2d(kernel_size=5, stride=6) + ) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + if m is final_conv: + init.normal(m.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(m.weight.data) + if m.bias is not None: + m.bias.data.zero_() + +
[docs] def forward(self, x, metadata): + x = self.pre_metadata_features(x) + x = torch.cat((x, metadata), 1) + x = self.post_metadata_features(x) + x = self.final_output_Aruco(x) + x = x.view(x.size(0), -1) + return x
+ + +
[docs]def unit_test(): + test_net = SqueezeNet() + a = test_net( + Variable( + torch.randn( + 5, 12, 94, 168)), Variable( + torch.randn( + 5, 128, 23, 41))) + print(a)
+ + +unit_test() +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/Z2ColorBatchNorm.html b/docs/_build/html/_modules/training/nets/Z2ColorBatchNorm.html new file mode 100644 index 0000000..5d4b5bd --- /dev/null +++ b/docs/_build/html/_modules/training/nets/Z2ColorBatchNorm.html @@ -0,0 +1,304 @@ + + + + + + + + + + + training.nets.Z2ColorBatchNorm — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.Z2ColorBatchNorm
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.Z2ColorBatchNorm

+"""z2_color implementation with batch normalization."""
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from torch.autograd import Variable
+
+
+
[docs]class Z2ColorBatchNorm(nn.Module): + def __init__(self): + super(Z2ColorBatchNorm, self).__init__() + + self.lr = 0.1 + self.momentum = 0.1 + self.N_FRAMES = 2 + self.N_STEPS = 10 + + self.conv1 = nn.Conv2d( + in_channels=12, + out_channels=96, + kernel_size=11, + stride=3, + groups=1) + self.conv1_pool = nn.MaxPool2d(kernel_size=3, stride=2) + self.conv1_pool_norm = nn.BatchNorm2d(96) + + self.conv2 = nn.Conv2d( + in_channels=102, + out_channels=256, + kernel_size=3, + stride=2, + groups=2) + self.conv2_pool = nn.MaxPool2d(kernel_size=3, stride=2) + self.conv2_pool_norm = nn.BatchNorm2d(256) + self.ip1 = nn.Linear(in_features=2560, out_features=512) + self.ip1_norm = nn.BatchNorm1d(512) + self.ip2 = nn.Linear(in_features=512, out_features=20) + + # Initialize weights + nn.init.normal(self.conv1.weight, std=0.00001) + nn.init.normal(self.conv2.weight, std=0.1) + + nn.init.xavier_normal(self.ip1.weight) + nn.init.xavier_normal(self.ip2.weight) + +
[docs] def forward(self, x, metadata): + # conv1 + x = self.conv1(x) + x = F.relu(x) + x = self.conv1_pool(x) + x = self.conv1_pool_norm(x) + + # metadata_concat + x = torch.cat((metadata, x), 1) + + # conv2 + x = self.conv2_pool_norm(self.conv2_pool(F.relu(self.conv2(x)))) + + x = x.view(-1, 2560) + + # ip1 + x = self.ip1_norm(F.relu(self.ip1(x))) + + # ip2 + x = self.ip2(x) + + return x
+ + +
[docs]def unit_test(): + test_net = Z2ColorBatchNorm() + a = test_net( + Variable( + torch.randn( + 5, 12, 94, 168)), Variable( + torch.randn( + 5, 6, 13, 26))) + print(a)
+ + +unit_test() +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/nonsqueeze/Feedforward.html b/docs/_build/html/_modules/training/nets/eric/nonsqueeze/Feedforward.html new file mode 100644 index 0000000..70b3e18 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/nonsqueeze/Feedforward.html @@ -0,0 +1,294 @@ + + + + + + + + + + + training.nets.eric.nonsqueeze.Feedforward — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.nonsqueeze.Feedforward
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.nonsqueeze.Feedforward

+"""SqueezeNet 1.1 modified for regression."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+import logging
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
[docs]class Feedforward(nn.Module): + + def __init__(self, n_steps=10, n_frames=2): + super(Feedforward, self).__init__() + + self.n_steps = n_steps + self.n_frames = n_frames + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2 * n_frames, 8, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + nn.Conv2d(8, 8, kernel_size=3, padding=1) + ) + self.post_metadata_features = nn.Sequential( + nn.Conv2d(16, 12, kernel_size=3, padding=1), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + nn.Conv2d(12, 12, kernel_size=3, padding=1), + nn.Conv2d(12, 16, kernel_size=3, padding=1), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + nn.Conv2d(16, 16, kernel_size=3, padding=1), + nn.Conv2d(16, 24, kernel_size=3, padding=1), + nn.Conv2d(24, 24, kernel_size=3, padding=1) + ) + final_conv = nn.Conv2d(24, self.n_steps * 2, kernel_size=1) + self.final_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + # nn.ReLU(inplace=True), + nn.AvgPool2d(kernel_size=5, stride=5) + ) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + if m is final_conv: + init.normal(m.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(m.weight.data) + if m.bias is not None: + m.bias.data.zero_() + +
[docs] def forward(self, x, metadata): + x = self.pre_metadata_features(x) + x = torch.cat((x, metadata), 1) + x = self.post_metadata_features(x) + x = self.final_output(x) + x = x.view(x.size(0), -1) + return x
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + test_net = Feedforward(20, 6) + a = test_net(Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 8, 23, 41))) + logging.debug('Net Test Output = {}'.format(a)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = Feedforward +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/nonsqueeze/Nvidia.html b/docs/_build/html/_modules/training/nets/eric/nonsqueeze/Nvidia.html new file mode 100644 index 0000000..8a4d0a0 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/nonsqueeze/Nvidia.html @@ -0,0 +1,273 @@ + + + + + + + + + + + training.nets.eric.nonsqueeze.Nvidia — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.nonsqueeze.Nvidia
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.nonsqueeze.Nvidia

+"""SqueezeNet 1.1 modified for regression."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+import logging
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
[docs]class Nvidia(nn.Module): + + def __init__(self, n_steps=10, n_frames=2): + super(Nvidia, self).__init__() + + self.n_steps = n_steps + self.n_frames = n_frames + self.conv_nets = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 24, kernel_size=5, stride=2), + nn.Conv2d(24, 36, kernel_size=5, stride=2), + nn.Conv2d(36, 48, kernel_size=5, stride=2), + nn.Conv2d(48, 64, kernel_size=3, stride=2), + nn.Conv2d(64, 64, kernel_size=3, stride=1) + ) + self.fcl = nn.Sequential( + nn.Linear(768, 100), + nn.Linear(100, 4 * self.n_steps) + ) + + +
[docs] def forward(self, x, metadata): + x = self.conv_nets(x) + x = x.view(x.size(0), -1) + x = self.fcl(x) + x = x.view(x.size(0), -1, 4) + return x
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + test_net = Nvidia(20, 6) + a = test_net(Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 12, 23, 41))) + logging.debug('Net Test Output = {}'.format(a)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = Nvidia +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/nonsqueeze/NvidiaMetadata.html b/docs/_build/html/_modules/training/nets/eric/nonsqueeze/NvidiaMetadata.html new file mode 100644 index 0000000..ffa0aa5 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/nonsqueeze/NvidiaMetadata.html @@ -0,0 +1,277 @@ + + + + + + + + + + + training.nets.eric.nonsqueeze.NvidiaMetadata — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.nonsqueeze.NvidiaMetadata
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.nonsqueeze.NvidiaMetadata

+"""SqueezeNet 1.1 modified for regression."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+import logging
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
[docs]class NvidiaMetadata(nn.Module): + + def __init__(self, n_steps=10, n_frames=2): + super(NvidiaMetadata, self).__init__() + + self.n_steps = n_steps + self.n_frames = n_frames + self.pre_metadata = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 24, kernel_size=5, stride=2), + nn.Conv2d(24, 36, kernel_size=5, stride=2) + ) + self.post_metadata = nn.Sequential( + nn.Conv2d(48, 48, kernel_size=5, stride=2), + nn.Conv2d(48, 64, kernel_size=3, stride=2), + nn.Conv2d(64, 64, kernel_size=3, stride=1) + ) + self.fcl = nn.Sequential( + nn.Linear(768, 100), + nn.Linear(100, 4 * self.n_steps) + ) + + +
[docs] def forward(self, x, metadata): + x = self.pre_metadata(x) + x = torch.cat([x, metadata], 1) + x = self.post_metadata(x) + x = x.view(x.size(0), -1) + x = self.fcl(x) + x = x.view(x.size(0), -1, 4) + return x
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + test_net = NvidiaMetadata(20, 6) + a = test_net(Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 12, 21, 39))) + logging.debug('Net Test Output = {}'.format(a)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = NvidiaMetadata +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/nonsqueeze/TimeLSTM.html b/docs/_build/html/_modules/training/nets/eric/nonsqueeze/TimeLSTM.html new file mode 100644 index 0000000..aac5fa0 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/nonsqueeze/TimeLSTM.html @@ -0,0 +1,363 @@ + + + + + + + + + + + training.nets.eric.nonsqueeze.TimeLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.nonsqueeze.TimeLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.nonsqueeze.TimeLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import logging
+
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+# from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetTimeLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_frames=2, n_steps=10): + """Sets up layers""" + super(SqueezeNetTimeLSTM, self).__init__() + + self.is_cuda = False + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2, 8, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + nn.Conv2d(8, 8, kernel_size=3, padding=1) + ) + self.post_metadata_features = nn.Sequential( + nn.Conv2d(16, 12, kernel_size=3, padding=1), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + nn.Conv2d(12, 12, kernel_size=3, padding=1), + nn.Conv2d(12, 16, kernel_size=3, padding=1), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + nn.Conv2d(16, 16, kernel_size=3, padding=1), + nn.Conv2d(16, 24, kernel_size=3, padding=1), + nn.Conv2d(24, 8, kernel_size=3, padding=1) + ) + final_conv = nn.Conv2d(8, 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstm_encoder = nn.ModuleList([ + nn.LSTM(16, 32, 1, batch_first=True) + ]) + self.lstm_decoder = nn.ModuleList([ + nn.LSTM(1, 32, 1, batch_first=True), + nn.LSTM(32, 4, 1, batch_first=True) + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetTimeLSTM""" + batch_size = camera_data.size(0) + nframes = camera_data.size(1) // 6 + metadata = metadata.contiguous().view(-1, 8, 23, 41) + net_output = camera_data.contiguous().view(-1, 6, 94, 168) + net_output = self.pre_metadata_features(net_output) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.contiguous().view(batch_size, -1, 16) + for lstm in self.lstm_encoder: + net_output, last_hidden_cell = lstm(net_output) + last_hidden_cell = list(last_hidden_cell) + for lstm in self.lstm_decoder: + if last_hidden_cell: + # last_hidden_cell[0] = last_hidden_cell[0].contiguous().view(batch_size, -1, 256) + # last_hidden_cell[1] = last_hidden_cell[1].contiguous().view(batch_size, -1, 256) + net_output = lstm(self.get_decoder_seq(batch_size, self.n_steps), last_hidden_cell)[0] + last_hidden_cell = None + else: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def get_decoder_seq(self, batch_size, timesteps): + decoder_input_seq = Variable(torch.zeros(batch_size, timesteps, 1)) + return decoder_input_seq.cuda() if self.is_cuda else decoder_input_seq
+ +
[docs] def cuda(self, device_id=None): + self.is_cuda = True + return super(SqueezeNetTimeLSTM, self).cuda(device_id)
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + """Tests SqueezeNetTimeLSTM for size constitency""" + test_net = SqueezeNetTimeLSTM(6, 20) + test_net_output = test_net( + Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 8, 6, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNetTimeLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNet.html b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNet.html new file mode 100644 index 0000000..2d4c7f7 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNet.html @@ -0,0 +1,319 @@ + + + + + + + + + + + training.nets.eric.smallmodels.SqueezeNet — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.smallmodels.SqueezeNet
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.smallmodels.SqueezeNet

+"""SqueezeNet 1.1 modified for regression."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+import logging
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+
[docs]class Fire(nn.Module): + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, x): + x = self.squeeze_activation(self.squeeze(x)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(x)), + self.expand3x3_activation(self.expand3x3(x)) + ], 1)
+ + +
[docs]class SqueezeNet(nn.Module): + + def __init__(self, n_steps=10, n_frames=2): + super(SqueezeNet, self).__init__() + + self.n_steps = n_steps + self.n_frames = n_frames + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 6, 12, 12) + ) + self.post_metadata_features = nn.Sequential( + Fire(36, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + Fire(64, 24, 48, 48), + Fire(96, 24, 48, 48), + ) + final_conv = nn.Conv2d(96, self.n_steps * 4, kernel_size=1) + self.final_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + # nn.ReLU(inplace=True), + nn.AvgPool2d(kernel_size=5, stride=6) + ) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + if m is final_conv: + init.normal(m.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(m.weight.data) + if m.bias is not None: + m.bias.data.zero_() + +
[docs] def forward(self, x, metadata): + x = self.pre_metadata_features(x) + x = torch.cat((x, metadata), 1) + x = self.post_metadata_features(x) + x = self.final_output(x) + x = x.view(x.size(0), -1) + return x
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + test_net = SqueezeNet(20, 6) + a = test_net(Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 12, 23, 41))) + logging.debug('Net Test Output = {}'.format(a)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNet +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetLSTM.html b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetLSTM.html new file mode 100644 index 0000000..262fc1b --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetLSTM.html @@ -0,0 +1,336 @@ + + + + + + + + + + + training.nets.eric.smallmodels.SqueezeNetLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.smallmodels.SqueezeNetLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.smallmodels.SqueezeNetLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+import logging
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+#from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_frames=2, n_steps=10): + """Sets up layers""" + super(SqueezeNetLSTM, self).__init__() + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 6, 12, 12) + ) + self.post_metadata_features = nn.Sequential( + Fire(36, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + Fire(64, 24, 48, 48), + Fire(96, 24, 48, 48), + ) + final_conv = nn.Conv2d(96, self.n_steps * 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstms = nn.ModuleList([ + nn.LSTM(16, 32, 2, batch_first=True), + nn.LSTM(32, 4, 1, batch_first=True) + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetLSTM""" + net_output = self.pre_metadata_features(camera_data) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.view(net_output.size(0), self.n_steps, -1) + for lstm in self.lstms: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ + +
[docs]def unit_test(): + """Tests SqueezeNetLSTM for size constitency""" + test_net = SqueezeNetLSTM() + test_net_output = test_net( + Variable(torch.randn(5, 12, 94, 168)), + Variable(torch.randn(5, 12, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNetLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetSqueezeLSTM.html b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetSqueezeLSTM.html new file mode 100644 index 0000000..e73bacd --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetSqueezeLSTM.html @@ -0,0 +1,342 @@ + + + + + + + + + + + training.nets.eric.smallmodels.SqueezeNetSqueezeLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.smallmodels.SqueezeNetSqueezeLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.smallmodels.SqueezeNetSqueezeLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import logging
+
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+# from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetSqueezeLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_steps=10, n_frames=2): + """Sets up layers""" + super(SqueezeNetSqueezeLSTM, self).__init__() + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 6, 12, 12) + ) + self.post_metadata_features = nn.Sequential( + Fire(36, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + Fire(64, 24, 48, 48), + Fire(96, 24, 48, 48), + ) + final_conv = nn.Conv2d(96, self.n_steps * 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstms = nn.ModuleList([ + nn.LSTM(16, 32, 1, batch_first=True), + nn.LSTM(32, 8, 1, batch_first=True), + nn.LSTM(8, 16, 1, batch_first=True), + nn.LSTM(16, 4, 1, batch_first=True) + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetSqueezeLSTM""" + net_output = self.pre_metadata_features(camera_data) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.view(net_output.size(0), self.n_steps, -1) + for lstm in self.lstms: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ + +
[docs]def unit_test(): + """Tests SqueezeNetSqueezeLSTM for size constitency""" + test_net = SqueezeNetSqueezeLSTM(20, 6) + test_net_output = test_net( + Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 12, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ # for param in test_net.parameters(): + + +unit_test() +Net = SqueezeNetSqueezeLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetSqueezeTimeLSTM.html b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetSqueezeTimeLSTM.html new file mode 100644 index 0000000..097b18e --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetSqueezeTimeLSTM.html @@ -0,0 +1,366 @@ + + + + + + + + + + + training.nets.eric.smallmodels.SqueezeNetSqueezeTimeLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.smallmodels.SqueezeNetSqueezeTimeLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.smallmodels.SqueezeNetSqueezeTimeLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import logging
+
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+# from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetTimeLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_frames=2, n_steps=10): + """Sets up layers""" + super(SqueezeNetTimeLSTM, self).__init__() + + self.is_cuda = False + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 6, 12, 12) + ) + self.post_metadata_features = nn.Sequential( + Fire(36, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + Fire(64, 24, 48, 48), + Fire(96, 24, 48, 48), + ) + final_conv = nn.Conv2d(96, 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstm_encoder = nn.ModuleList([ + nn.LSTM(16, 32, 1, batch_first=True) + ]) + self.lstm_decoder = nn.ModuleList([ + nn.LSTM(1, 32, 1, batch_first=True), + nn.LSTM(32, 8, 1, batch_first=True), + nn.LSTM(8, 16, 1, batch_first=True), + nn.LSTM(16, 4, 1, batch_first=True), + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetTimeLSTM""" + batch_size = camera_data.size(0) + nframes = camera_data.size(1) // 6 + metadata = metadata.contiguous().view(-1, 12, 23, 41) + net_output = camera_data.contiguous().view(-1, 6, 94, 168) + net_output = self.pre_metadata_features(net_output) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.contiguous().view(batch_size, -1, 16) + for lstm in self.lstm_encoder: + net_output, last_hidden_cell = lstm(net_output) + last_hidden_cell = list(last_hidden_cell) + for lstm in self.lstm_decoder: + if last_hidden_cell: + # last_hidden_cell[0] = last_hidden_cell[0].contiguous().view(batch_size, -1, 256) + # last_hidden_cell[1] = last_hidden_cell[1].contiguous().view(batch_size, -1, 256) + net_output = lstm(self.get_decoder_seq(batch_size, self.n_steps), last_hidden_cell)[0] + last_hidden_cell = None + else: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def get_decoder_seq(self, batch_size, timesteps): + decoder_input_seq = Variable(torch.zeros(batch_size, timesteps, 1)) + return decoder_input_seq.cuda() if self.is_cuda else decoder_input_seq
+ +
[docs] def cuda(self, device_id=None): + self.is_cuda = True + return super(SqueezeNetTimeLSTM, self).cuda(device_id)
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + """Tests SqueezeNetTimeLSTM for size constitency""" + test_net = SqueezeNetTimeLSTM(6, 20) + test_net_output = test_net( + Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 12, 6, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNetTimeLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetTimeLSTM.html b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetTimeLSTM.html new file mode 100644 index 0000000..5b72e7e --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/smallmodels/SqueezeNetTimeLSTM.html @@ -0,0 +1,364 @@ + + + + + + + + + + + training.nets.eric.smallmodels.SqueezeNetTimeLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.smallmodels.SqueezeNetTimeLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.smallmodels.SqueezeNetTimeLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import logging
+
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+# from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetTimeLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_frames=2, n_steps=10): + """Sets up layers""" + super(SqueezeNetTimeLSTM, self).__init__() + + self.is_cuda = False + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 6, 12, 12) + ) + self.post_metadata_features = nn.Sequential( + Fire(36, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + Fire(64, 24, 48, 48), + Fire(96, 24, 48, 48), + ) + final_conv = nn.Conv2d(96, 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstm_encoder = nn.ModuleList([ + nn.LSTM(16, 32, 1, batch_first=True) + ]) + self.lstm_decoder = nn.ModuleList([ + nn.LSTM(1, 32, 1, batch_first=True), + nn.LSTM(32, 4, 1, batch_first=True) + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetTimeLSTM""" + batch_size = camera_data.size(0) + nframes = camera_data.size(1) // 6 + metadata = metadata.contiguous().view(-1, 12, 23, 41) + net_output = camera_data.contiguous().view(-1, 6, 94, 168) + net_output = self.pre_metadata_features(net_output) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.contiguous().view(batch_size, -1, 16) + for lstm in self.lstm_encoder: + net_output, last_hidden_cell = lstm(net_output) + last_hidden_cell = list(last_hidden_cell) + for lstm in self.lstm_decoder: + if last_hidden_cell: + # last_hidden_cell[0] = last_hidden_cell[0].contiguous().view(batch_size, -1, 256) + # last_hidden_cell[1] = last_hidden_cell[1].contiguous().view(batch_size, -1, 256) + net_output = lstm(self.get_decoder_seq(batch_size, self.n_steps), last_hidden_cell)[0] + last_hidden_cell = None + else: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def get_decoder_seq(self, batch_size, timesteps): + decoder_input_seq = Variable(torch.zeros(batch_size, timesteps, 1)) + return decoder_input_seq.cuda() if self.is_cuda else decoder_input_seq
+ +
[docs] def cuda(self, device_id=None): + self.is_cuda = True + return super(SqueezeNetTimeLSTM, self).cuda(device_id)
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + """Tests SqueezeNetTimeLSTM for size constitency""" + test_net = SqueezeNetTimeLSTM(6, 20) + test_net_output = test_net( + Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 12, 6, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNetTimeLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNet.html b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNet.html new file mode 100644 index 0000000..3464b8b --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNet.html @@ -0,0 +1,319 @@ + + + + + + + + + + + training.nets.eric.tinymodels.SqueezeNet — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.tinymodels.SqueezeNet
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.tinymodels.SqueezeNet

+"""SqueezeNet 1.1 modified for regression."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+import logging
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+
[docs]class Fire(nn.Module): + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, x): + x = self.squeeze_activation(self.squeeze(x)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(x)), + self.expand3x3_activation(self.expand3x3(x)) + ], 1)
+ + +
[docs]class SqueezeNet(nn.Module): + + def __init__(self, n_steps=10, n_frames=2): + super(SqueezeNet, self).__init__() + + self.n_steps = n_steps + self.n_frames = n_frames + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 4, 8, 8) + ) + self.post_metadata_features = nn.Sequential( + Fire(24, 6, 12, 12), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(24, 8, 16, 16), + Fire(32, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + ) + final_conv = nn.Conv2d(64, self.n_steps * 2, kernel_size=1) + self.final_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + # nn.ReLU(inplace=True), + nn.AvgPool2d(kernel_size=5, stride=5) + ) + + for m in self.modules(): + if isinstance(m, nn.Conv2d): + if m is final_conv: + init.normal(m.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(m.weight.data) + if m.bias is not None: + m.bias.data.zero_() + +
[docs] def forward(self, x, metadata): + x = self.pre_metadata_features(x) + x = torch.cat((x, metadata), 1) + x = self.post_metadata_features(x) + x = self.final_output(x) + x = x.view(x.size(0), -1) + return x
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + test_net = SqueezeNet(20, 6) + a = test_net(Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 8, 23, 41))) + logging.debug('Net Test Output = {}'.format(a)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNet +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetLSTM.html b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetLSTM.html new file mode 100644 index 0000000..83f2ff2 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetLSTM.html @@ -0,0 +1,336 @@ + + + + + + + + + + + training.nets.eric.tinymodels.SqueezeNetLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.tinymodels.SqueezeNetLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.tinymodels.SqueezeNetLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+import logging
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+#from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_frames=2, n_steps=10): + """Sets up layers""" + super(SqueezeNetLSTM, self).__init__() + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 4, 8, 8) + ) + self.post_metadata_features = nn.Sequential( + Fire(24, 6, 12, 12), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(24, 8, 16, 16), + Fire(32, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + ) + final_conv = nn.Conv2d(64, self.n_steps * 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstms = nn.ModuleList([ + nn.LSTM(16, 32, 1, batch_first=True), + nn.LSTM(32, 4, 1, batch_first=True) + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetLSTM""" + net_output = self.pre_metadata_features(camera_data) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.view(net_output.size(0), self.n_steps, -1) + for lstm in self.lstms: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ + +
[docs]def unit_test(): + """Tests SqueezeNetLSTM for size constitency""" + test_net = SqueezeNetLSTM() + test_net_output = test_net( + Variable(torch.randn(5, 12, 94, 168)), + Variable(torch.randn(5, 8, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNetLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetSqueezeLSTM.html b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetSqueezeLSTM.html new file mode 100644 index 0000000..442bf09 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetSqueezeLSTM.html @@ -0,0 +1,342 @@ + + + + + + + + + + + training.nets.eric.tinymodels.SqueezeNetSqueezeLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.tinymodels.SqueezeNetSqueezeLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.tinymodels.SqueezeNetSqueezeLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import logging
+
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+# from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetSqueezeLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_steps=10, n_frames=2): + """Sets up layers""" + super(SqueezeNetSqueezeLSTM, self).__init__() + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2 * self.n_frames, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 4, 8, 8) + ) + self.post_metadata_features = nn.Sequential( + Fire(24, 6, 12, 12), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(24, 8, 16, 16), + Fire(32, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + ) + final_conv = nn.Conv2d(64, self.n_steps * 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstms = nn.ModuleList([ + nn.LSTM(16, 32, 1, batch_first=True), + nn.LSTM(32, 8, 1, batch_first=True), + nn.LSTM(8, 16, 1, batch_first=True), + nn.LSTM(16, 4, 1, batch_first=True) + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetSqueezeLSTM""" + net_output = self.pre_metadata_features(camera_data) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.view(net_output.size(0), self.n_steps, -1) + for lstm in self.lstms: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ + +
[docs]def unit_test(): + """Tests SqueezeNetSqueezeLSTM for size constitency""" + test_net = SqueezeNetSqueezeLSTM(20, 6) + test_net_output = test_net( + Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 8, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ # for param in test_net.parameters(): + + +unit_test() +Net = SqueezeNetSqueezeLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetSqueezeTimeLSTM.html b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetSqueezeTimeLSTM.html new file mode 100644 index 0000000..666c77d --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetSqueezeTimeLSTM.html @@ -0,0 +1,366 @@ + + + + + + + + + + + training.nets.eric.tinymodels.SqueezeNetSqueezeTimeLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.tinymodels.SqueezeNetSqueezeTimeLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.tinymodels.SqueezeNetSqueezeTimeLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import logging
+
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+# from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetTimeLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_frames=2, n_steps=10): + """Sets up layers""" + super(SqueezeNetTimeLSTM, self).__init__() + + self.is_cuda = False + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 4, 8, 8) + ) + self.post_metadata_features = nn.Sequential( + Fire(24, 6, 12, 12), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(24, 8, 16, 16), + Fire(32, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + ) + final_conv = nn.Conv2d(64, 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstm_encoder = nn.ModuleList([ + nn.LSTM(16, 32, 1, batch_first=True) + ]) + self.lstm_decoder = nn.ModuleList([ + nn.LSTM(1, 32, 1, batch_first=True), + nn.LSTM(32, 8, 1, batch_first=True), + nn.LSTM(8, 16, 1, batch_first=True), + nn.LSTM(16, 4, 1, batch_first=True), + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetTimeLSTM""" + batch_size = camera_data.size(0) + nframes = camera_data.size(1) // 6 + metadata = metadata.contiguous().view(-1, 8, 23, 41) + net_output = camera_data.contiguous().view(-1, 6, 94, 168) + net_output = self.pre_metadata_features(net_output) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.contiguous().view(batch_size, -1, 16) + for lstm in self.lstm_encoder: + net_output, last_hidden_cell = lstm(net_output) + last_hidden_cell = list(last_hidden_cell) + for lstm in self.lstm_decoder: + if last_hidden_cell: + # last_hidden_cell[0] = last_hidden_cell[0].contiguous().view(batch_size, -1, 256) + # last_hidden_cell[1] = last_hidden_cell[1].contiguous().view(batch_size, -1, 256) + net_output = lstm(self.get_decoder_seq(batch_size, self.n_steps), last_hidden_cell)[0] + last_hidden_cell = None + else: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def get_decoder_seq(self, batch_size, timesteps): + decoder_input_seq = Variable(torch.zeros(batch_size, timesteps, 1)) + return decoder_input_seq.cuda() if self.is_cuda else decoder_input_seq
+ +
[docs] def cuda(self, device_id=None): + self.is_cuda = True + return super(SqueezeNetTimeLSTM, self).cuda(device_id)
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + """Tests SqueezeNetTimeLSTM for size constitency""" + test_net = SqueezeNetTimeLSTM(6, 20) + test_net_output = test_net( + Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 8, 6, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNetTimeLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetTimeLSTM.html b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetTimeLSTM.html new file mode 100644 index 0000000..159db54 --- /dev/null +++ b/docs/_build/html/_modules/training/nets/eric/tinymodels/SqueezeNetTimeLSTM.html @@ -0,0 +1,363 @@ + + + + + + + + + + + training.nets.eric.tinymodels.SqueezeNetTimeLSTM — BDD Model Car Training documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • Docs »
  • + +
  • Module code »
  • + +
  • training.nets.eric.tinymodels.SqueezeNetTimeLSTM
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ +

Source code for training.nets.eric.tinymodels.SqueezeNetTimeLSTM

+"""SqueezeNet 1.1 modified for LSTM regression."""
+import logging
+
+import torch
+import torch.nn as nn
+import torch.nn.init as init
+from torch.autograd import Variable
+
+logging.basicConfig(filename='training.log', level=logging.DEBUG)
+
+
+# from Parameters import ARGS
+
+
+
[docs]class Fire(nn.Module): # pylint: disable=too-few-public-methods + """Implementation of Fire module""" + + def __init__(self, inplanes, squeeze_planes, + expand1x1_planes, expand3x3_planes): + """Sets up layers for Fire module""" + super(Fire, self).__init__() + self.inplanes = inplanes + self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1) + self.squeeze_activation = nn.ReLU(inplace=True) + self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes, + kernel_size=1) + self.expand1x1_activation = nn.ReLU(inplace=True) + self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes, + kernel_size=3, padding=1) + self.expand3x3_activation = nn.ReLU(inplace=True) + +
[docs] def forward(self, input_data): + """Forward-propagates data through Fire module""" + output_data = self.squeeze_activation(self.squeeze(input_data)) + return torch.cat([ + self.expand1x1_activation(self.expand1x1(output_data)), + self.expand3x3_activation(self.expand3x3(output_data)) + ], 1)
+ + +
[docs]class SqueezeNetTimeLSTM(nn.Module): # pylint: disable=too-few-public-methods + """SqueezeNet+LSTM for end to end autonomous driving""" + + def __init__(self, n_frames=2, n_steps=10): + """Sets up layers""" + super(SqueezeNetTimeLSTM, self).__init__() + + self.is_cuda = False + + self.n_frames = n_frames + self.n_steps = n_steps + self.pre_metadata_features = nn.Sequential( + nn.Conv2d(3 * 2, 16, kernel_size=3, stride=2), + nn.ReLU(inplace=True), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(16, 4, 8, 8), + ) + self.post_metadata_features = nn.Sequential( + Fire(24, 6, 12, 12), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(24, 8, 16, 16), + Fire(32, 8, 16, 16), + nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True), + Fire(32, 12, 24, 24), + Fire(48, 12, 24, 24), + Fire(48, 16, 32, 32), + Fire(64, 16, 32, 32), + ) + final_conv = nn.Conv2d(64, 2, kernel_size=1) + self.pre_lstm_output = nn.Sequential( + nn.Dropout(p=0.5), + final_conv, + nn.AvgPool2d(kernel_size=3, stride=2), + ) + self.lstm_encoder = nn.ModuleList([ + nn.LSTM(16, 32, 1, batch_first=True) + ]) + self.lstm_decoder = nn.ModuleList([ + nn.LSTM(1, 32, 1, batch_first=True), + nn.LSTM(32, 4, 1, batch_first=True) + ]) + + for mod in self.modules(): + if isinstance(mod, nn.Conv2d): + if mod is final_conv: + init.normal(mod.weight.data, mean=0.0, std=0.01) + else: + init.kaiming_uniform(mod.weight.data) + if mod.bias is not None: + mod.bias.data.zero_() + +
[docs] def forward(self, camera_data, metadata): + """Forward-propagates data through SqueezeNetTimeLSTM""" + batch_size = camera_data.size(0) + metadata = metadata.contiguous().view(-1, 8, 23, 41) + net_output = camera_data.contiguous().view(-1, 6, 94, 168) + net_output = self.pre_metadata_features(net_output) + net_output = torch.cat((net_output, metadata), 1) + net_output = self.post_metadata_features(net_output) + net_output = self.pre_lstm_output(net_output) + net_output = net_output.contiguous().view(batch_size, -1, 16) + for lstm in self.lstm_encoder: + net_output, last_hidden_cell = lstm(net_output) + last_hidden_cell = list(last_hidden_cell) + for lstm in self.lstm_decoder: + if last_hidden_cell: + # last_hidden_cell[0] = last_hidden_cell[0].contiguous().view(batch_size, -1, 256) + # last_hidden_cell[1] = last_hidden_cell[1].contiguous().view(batch_size, -1, 256) + net_output = lstm(self.get_decoder_seq(batch_size, self.n_steps), last_hidden_cell)[0] + last_hidden_cell = None + else: + net_output = lstm(net_output)[0] + net_output = net_output.contiguous().view(net_output.size(0), -1) + return net_output
+ +
[docs] def get_decoder_seq(self, batch_size, timesteps): + decoder_input_seq = Variable(torch.zeros(batch_size, timesteps, 1)) + return decoder_input_seq.cuda() if self.is_cuda else decoder_input_seq
+ +
[docs] def cuda(self, device_id=None): + self.is_cuda = True + return super(SqueezeNetTimeLSTM, self).cuda(device_id)
+ +
[docs] def num_params(self): + return sum([reduce(lambda x, y: x * y, [dim for dim in p.size()], 1) for p in self.parameters()])
+ +
[docs]def unit_test(): + """Tests SqueezeNetTimeLSTM for size constitency""" + test_net = SqueezeNetTimeLSTM(6, 20) + test_net_output = test_net( + Variable(torch.randn(5, 36, 94, 168)), + Variable(torch.randn(5, 8, 6, 23, 41))) + logging.debug('Net Test Output = {}'.format(test_net_output)) + logging.debug('Network was Unit Tested') + print(test_net.num_params())
+ +unit_test() + +Net = SqueezeNetTimeLSTM +
+ +
+
+ +
+
+
+ + +
+ +
+

+ © Copyright 2017, Sauhaarda Chowdhuri. + +

+
+ Built with Sphinx using a theme provided by Read the Docs. + +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_sources/index.rst.txt b/docs/_build/html/_sources/index.rst.txt new file mode 100644 index 0000000..95bbf30 --- /dev/null +++ b/docs/_build/html/_sources/index.rst.txt @@ -0,0 +1,24 @@ +.. BDD Model Car Training documentation master file, created by + sphinx-quickstart on Sat Dec 23 21:19:21 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to BDD Model Car Training's documentation! +================================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + source/modules + wiki/computersetup + wiki/computermonitor + wiki/dataset + wiki/TX2 + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/_build/html/_sources/source/modules.rst.txt b/docs/_build/html/_sources/source/modules.rst.txt new file mode 100644 index 0000000..54b4dcc --- /dev/null +++ b/docs/_build/html/_sources/source/modules.rst.txt @@ -0,0 +1,7 @@ +training +======== + +.. toctree:: + :maxdepth: 4 + + training diff --git a/docs/_build/html/_sources/source/training.nets.eric.nonsqueeze.rst.txt b/docs/_build/html/_sources/source/training.nets.eric.nonsqueeze.rst.txt new file mode 100644 index 0000000..2b5cda4 --- /dev/null +++ b/docs/_build/html/_sources/source/training.nets.eric.nonsqueeze.rst.txt @@ -0,0 +1,46 @@ +training\.nets\.eric\.nonsqueeze package +======================================== + +Submodules +---------- + +training\.nets\.eric\.nonsqueeze\.Feedforward module +---------------------------------------------------- + +.. automodule:: training.nets.eric.nonsqueeze.Feedforward + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.nonsqueeze\.Nvidia module +----------------------------------------------- + +.. automodule:: training.nets.eric.nonsqueeze.Nvidia + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.nonsqueeze\.NvidiaMetadata module +------------------------------------------------------- + +.. automodule:: training.nets.eric.nonsqueeze.NvidiaMetadata + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.nonsqueeze\.TimeLSTM module +------------------------------------------------- + +.. automodule:: training.nets.eric.nonsqueeze.TimeLSTM + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: training.nets.eric.nonsqueeze + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_build/html/_sources/source/training.nets.eric.rst.txt b/docs/_build/html/_sources/source/training.nets.eric.rst.txt new file mode 100644 index 0000000..d4d4a53 --- /dev/null +++ b/docs/_build/html/_sources/source/training.nets.eric.rst.txt @@ -0,0 +1,19 @@ +training\.nets\.eric package +============================ + +Subpackages +----------- + +.. toctree:: + + training.nets.eric.nonsqueeze + training.nets.eric.smallmodels + training.nets.eric.tinymodels + +Module contents +--------------- + +.. automodule:: training.nets.eric + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_build/html/_sources/source/training.nets.eric.smallmodels.rst.txt b/docs/_build/html/_sources/source/training.nets.eric.smallmodels.rst.txt new file mode 100644 index 0000000..03e0791 --- /dev/null +++ b/docs/_build/html/_sources/source/training.nets.eric.smallmodels.rst.txt @@ -0,0 +1,54 @@ +training\.nets\.eric\.smallmodels package +========================================= + +Submodules +---------- + +training\.nets\.eric\.smallmodels\.SqueezeNet module +---------------------------------------------------- + +.. automodule:: training.nets.eric.smallmodels.SqueezeNet + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.smallmodels\.SqueezeNetLSTM module +-------------------------------------------------------- + +.. automodule:: training.nets.eric.smallmodels.SqueezeNetLSTM + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.smallmodels\.SqueezeNetSqueezeLSTM module +--------------------------------------------------------------- + +.. automodule:: training.nets.eric.smallmodels.SqueezeNetSqueezeLSTM + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.smallmodels\.SqueezeNetSqueezeTimeLSTM module +------------------------------------------------------------------- + +.. automodule:: training.nets.eric.smallmodels.SqueezeNetSqueezeTimeLSTM + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.smallmodels\.SqueezeNetTimeLSTM module +------------------------------------------------------------ + +.. automodule:: training.nets.eric.smallmodels.SqueezeNetTimeLSTM + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: training.nets.eric.smallmodels + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_build/html/_sources/source/training.nets.eric.tinymodels.rst.txt b/docs/_build/html/_sources/source/training.nets.eric.tinymodels.rst.txt new file mode 100644 index 0000000..e30d713 --- /dev/null +++ b/docs/_build/html/_sources/source/training.nets.eric.tinymodels.rst.txt @@ -0,0 +1,54 @@ +training\.nets\.eric\.tinymodels package +======================================== + +Submodules +---------- + +training\.nets\.eric\.tinymodels\.SqueezeNet module +--------------------------------------------------- + +.. automodule:: training.nets.eric.tinymodels.SqueezeNet + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.tinymodels\.SqueezeNetLSTM module +------------------------------------------------------- + +.. automodule:: training.nets.eric.tinymodels.SqueezeNetLSTM + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.tinymodels\.SqueezeNetSqueezeLSTM module +-------------------------------------------------------------- + +.. automodule:: training.nets.eric.tinymodels.SqueezeNetSqueezeLSTM + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.tinymodels\.SqueezeNetSqueezeTimeLSTM module +------------------------------------------------------------------ + +.. automodule:: training.nets.eric.tinymodels.SqueezeNetSqueezeTimeLSTM + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.eric\.tinymodels\.SqueezeNetTimeLSTM module +----------------------------------------------------------- + +.. automodule:: training.nets.eric.tinymodels.SqueezeNetTimeLSTM + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: training.nets.eric.tinymodels + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_build/html/_sources/source/training.nets.rst.txt b/docs/_build/html/_sources/source/training.nets.rst.txt new file mode 100644 index 0000000..c1d2438 --- /dev/null +++ b/docs/_build/html/_sources/source/training.nets.rst.txt @@ -0,0 +1,45 @@ +training\.nets package +====================== + +Subpackages +----------- + +.. toctree:: + + training.nets.eric + +Submodules +---------- + +training\.nets\.SqueezeNet module +--------------------------------- + +.. automodule:: training.nets.SqueezeNet + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.SqueezeNetAruco1 module +--------------------------------------- + +.. automodule:: training.nets.SqueezeNetAruco1 + :members: + :undoc-members: + :show-inheritance: + +training\.nets\.Z2ColorBatchNorm module +--------------------------------------- + +.. automodule:: training.nets.Z2ColorBatchNorm + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: training.nets + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_build/html/_sources/source/training.rst.txt b/docs/_build/html/_sources/source/training.rst.txt new file mode 100644 index 0000000..a81ab55 --- /dev/null +++ b/docs/_build/html/_sources/source/training.rst.txt @@ -0,0 +1,69 @@ +training package +================ + +Subpackages +----------- + +.. toctree:: + + training.nets + +Submodules +---------- + +training\.ArucoDataset module +----------------------------- + +.. automodule:: training.ArucoDataset + :members: + :undoc-members: + :show-inheritance: + +training\.Config module +----------------------- + +.. automodule:: training.Config + :members: + :undoc-members: + :show-inheritance: + +training\.Dataset module +------------------------ + +.. automodule:: training.Dataset + :members: + :undoc-members: + :show-inheritance: + +training\.Parameters module +--------------------------- + +.. automodule:: training.Parameters + :members: + :undoc-members: + :show-inheritance: + +training\.Train module +---------------------- + +.. automodule:: training.Train + :members: + :undoc-members: + :show-inheritance: + +training\.Utils module +---------------------- + +.. automodule:: training.Utils + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: training + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_build/html/_sources/wiki/TX2.md.txt b/docs/_build/html/_sources/wiki/TX2.md.txt new file mode 100644 index 0000000..f210fac --- /dev/null +++ b/docs/_build/html/_sources/wiki/TX2.md.txt @@ -0,0 +1,5 @@ +# TX2 +## TX2 Cloning +TX2 Cloning can be a complicated process, but it is extremely useful to setup multiple TX2s all running the same inference code in a short period of time. It is much faster than compiling PyTorch/Caffe and installing all necessary components. Here is a guide I wrote on how to clone the TX2 properly: + +[https://slack-files.com/T62KXFY93-F6DPGDJP3-f7185694c1](https://slack-files.com/T62KXFY93-F6DPGDJP3-f7185694c1) diff --git a/docs/_build/html/_sources/wiki/computermonitor.md.txt b/docs/_build/html/_sources/wiki/computermonitor.md.txt new file mode 100644 index 0000000..d10a83b --- /dev/null +++ b/docs/_build/html/_sources/wiki/computermonitor.md.txt @@ -0,0 +1,153 @@ +# Computer Monitoring + +## Run once per client machine + +### Install distributed shell +#### Linux +```bash +sudo apt-get --assume-yes install dsh +``` +#### Mac OSX +http://macappstore.org/dsh/ + + +### Setup Config Files +#### Now create a `~/.ssh/config` file and add all of the machines to it. Here is an example: +``` +Host bdd3.tspankaj.com + User sauhaarda + Port 1022 +Host bdd6.tspankaj.com + User sauhaarda + Port 1022 +Host bdd5.neuro.berkeley.edu + User sauhaarda + Port 1022 +Host bdd4.dyn.berkeley.edu + User sauhaarda + Port 1022 +``` + +#### Create a `~/.dsh/machines.list` file. In this file put in all of the host names from your ssh config. Here is an example: +``` +bdd3.tspankaj.com +bdd6.tspankaj.com +bdd4.dyn.berkeley.edu +bdd5.neuro.berkeley.edu +``` + +#### Finally add an alias to allow for even easier access for monitoring computers: +```bash +echo "alias monitorall='dsh -Mac -- remote-log'" >> ~/.bashrc + +## Finished! +``` +Now you'll be able to run `monitorall` anytime you want to see the status of each computer. The output will look something like this: +``` +bdd5.dyn.berkeley.edu: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND +bdd5.dyn.berkeley.edu: 30193 root 20 0 30.638g 6.504g 528376 R 93.3 5.2 23:02.27 python +bdd5.dyn.berkeley.edu: Wed Aug 16 21:10:31 2017 +bdd5.dyn.berkeley.edu: +-----------------------------------------------------------------------------+ +bdd5.dyn.berkeley.edu: | NVIDIA-SMI 375.66 Driver Version: 375.66 | +bdd5.dyn.berkeley.edu: |-------------------------------+----------------------+----------------------+ +bdd5.dyn.berkeley.edu: | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | +bdd5.dyn.berkeley.edu: | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | +bdd5.dyn.berkeley.edu: |===============================+======================+======================| +bdd5.dyn.berkeley.edu: | 0 GeForce GTX 108... Off | 0000:4B:00.0 Off | N/A | +bdd5.dyn.berkeley.edu: | 28% 38C P8 16W / 250W | 2MiB / 11172MiB | 0% Default | +bdd5.dyn.berkeley.edu: +-------------------------------+----------------------+----------------------+ +bdd5.dyn.berkeley.edu: | 1 GeForce GTX 108... Off | 0000:4C:00.0 Off | N/A | +bdd5.dyn.berkeley.edu: | 55% 79C P2 81W / 250W | 1877MiB / 11170MiB | 22% Default | +bdd5.dyn.berkeley.edu: +-------------------------------+----------------------+----------------------+ +bdd5.dyn.berkeley.edu: +bdd5.dyn.berkeley.edu: +-----------------------------------------------------------------------------+ +bdd5.dyn.berkeley.edu: | Processes: GPU Memory | +bdd5.dyn.berkeley.edu: | GPU PID Type Process name Usage | +bdd5.dyn.berkeley.edu: |=============================================================================| +bdd5.dyn.berkeley.edu: | 1 30193 C python 1875MiB | +bdd5.dyn.berkeley.edu: +-----------------------------------------------------------------------------+ +bdd3.tspankaj.com: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND +bdd3.tspankaj.com: 10854 bala 20 0 40.226g 0.012t 166016 R 86.7 9.9 449:50.57 python +bdd3.tspankaj.com: 10875 bala 20 0 41.614g 0.014t 165668 R 100.0 11.0 523:46.08 python +bdd3.tspankaj.com: 11149 bala 20 0 29.662g 6.465g 86512 R 80.0 5.1 499:47.42 python +bdd3.tspankaj.com: 11393 bala 20 0 30.072g 6.391g 86568 R 73.3 5.1 463:29.35 python +bdd3.tspankaj.com: 31902 bala 20 0 29.506g 6.038g 87740 R 86.7 4.8 171:49.60 python +bdd3.tspankaj.com: 10854 bala 20 0 40.226g 0.012t 166016 R 66.7 9.9 449:51.16 python +bdd3.tspankaj.com: 10875 bala 20 0 41.614g 0.014t 165668 R 81.2 11.0 523:46.79 python +bdd3.tspankaj.com: Wed Aug 16 21:10:32 2017 +bdd3.tspankaj.com: +-----------------------------------------------------------------------------+ +bdd3.tspankaj.com: | NVIDIA-SMI 375.66 Driver Version: 375.66 | +bdd3.tspankaj.com: |-------------------------------+----------------------+----------------------+ +bdd3.tspankaj.com: | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | +bdd3.tspankaj.com: | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | +bdd3.tspankaj.com: |===============================+======================+======================| +bdd3.tspankaj.com: | 0 TITAN X (Pascal) Off | 0000:4C:00.0 Off | N/A | +bdd3.tspankaj.com: | 41% 69C P2 184W / 250W | 6103MiB / 12189MiB | 74% Default | +bdd3.tspankaj.com: +-------------------------------+----------------------+----------------------+ +bdd3.tspankaj.com: | 1 TITAN X (Pascal) Off | 0000:4D:00.0 Off | N/A | +bdd3.tspankaj.com: | 51% 84C P2 104W / 250W | 3728MiB / 12186MiB | 17% Default | +bdd3.tspankaj.com: +-------------------------------+----------------------+----------------------+ +bdd3.tspankaj.com: +bdd3.tspankaj.com: +-----------------------------------------------------------------------------+ +bdd3.tspankaj.com: | Processes: GPU Memory | +bdd3.tspankaj.com: | GPU PID Type Process name Usage | +bdd3.tspankaj.com: |=============================================================================| +bdd3.tspankaj.com: | 0 10854 C python 315MiB | +bdd3.tspankaj.com: | 0 10875 C python 315MiB | +bdd3.tspankaj.com: | 0 11149 C python 1565MiB | +bdd3.tspankaj.com: | 0 11393 C python 2067MiB | +bdd3.tspankaj.com: | 0 31902 C python 1839MiB | +bdd3.tspankaj.com: | 1 10854 C python 1863MiB | +bdd3.tspankaj.com: | 1 10875 C python 1863MiB | +bdd3.tspankaj.com: +-----------------------------------------------------------------------------+ +bdd6.tspankaj.com: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND +bdd6.tspankaj.com: 10323 tpankaj 20 0 45.916g 0.021t 89460 R 553.3 34.8 7462:51 python +bdd6.tspankaj.com: 10412 tpankaj 20 0 45.972g 0.022t 89444 R 546.7 36.0 7469:08 python +bdd6.tspankaj.com: 23431 tpankaj 20 0 33.389g 0.011t 88680 R 46.7 17.7 280:30.31 python +bdd6.tspankaj.com: 17937 root 20 0 218564 11612 10968 S 0.0 0.0 0:12.94 Xorg +bdd6.tspankaj.com: Wed Aug 16 21:10:32 2017 +bdd6.tspankaj.com: +-----------------------------------------------------------------------------+ +bdd6.tspankaj.com: | NVIDIA-SMI 375.66 Driver Version: 375.66 | +bdd6.tspankaj.com: |-------------------------------+----------------------+----------------------+ +bdd6.tspankaj.com: | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | +bdd6.tspankaj.com: | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | +bdd6.tspankaj.com: |===============================+======================+======================| +bdd6.tspankaj.com: | 0 GeForce GTX 108... Off | 0000:4B:00.0 Off | N/A | +bdd6.tspankaj.com: | 47% 67C P2 82W / 250W | 4034MiB / 11172MiB | 9% Default | +bdd6.tspankaj.com: +-------------------------------+----------------------+----------------------+ +bdd6.tspankaj.com: | 1 GeForce GTX 108... Off | 0000:4C:00.0 On | N/A | +bdd6.tspankaj.com: | 40% 58C P8 30W / 250W | 55MiB / 11169MiB | 0% Default | +bdd6.tspankaj.com: +-------------------------------+----------------------+----------------------+ +bdd6.tspankaj.com: +bdd6.tspankaj.com: +-----------------------------------------------------------------------------+ +bdd6.tspankaj.com: | Processes: GPU Memory | +bdd6.tspankaj.com: | GPU PID Type Process name Usage | +bdd6.tspankaj.com: |=============================================================================| +bdd6.tspankaj.com: | 0 10323 C python 1585MiB | +bdd6.tspankaj.com: | 0 10412 C python 1585MiB | +bdd6.tspankaj.com: | 0 23431 C python 861MiB | +bdd6.tspankaj.com: | 1 17937 G /usr/lib/xorg/Xorg 50MiB | +bdd6.tspankaj.com: +-----------------------------------------------------------------------------+ +bdd4.dyn.berkeley.edu: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND +bdd4.dyn.berkeley.edu: 1334 root 20 0 219436 51404 36972 S 0.0 0.0 0:01.68 Xorg +bdd4.dyn.berkeley.edu: Wed Aug 16 21:10:32 2017 +bdd4.dyn.berkeley.edu: +-----------------------------------------------------------------------------+ +bdd4.dyn.berkeley.edu: | NVIDIA-SMI 375.82 Driver Version: 375.82 | +bdd4.dyn.berkeley.edu: |-------------------------------+----------------------+----------------------+ +bdd4.dyn.berkeley.edu: | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | +bdd4.dyn.berkeley.edu: | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | +bdd4.dyn.berkeley.edu: |===============================+======================+======================| +bdd4.dyn.berkeley.edu: | 0 TITAN X (Pascal) Off | 0000:4B:00.0 Off | N/A | +bdd4.dyn.berkeley.edu: | 23% 29C P8 8W / 250W | 1MiB / 12189MiB | 0% Default | +bdd4.dyn.berkeley.edu: +-------------------------------+----------------------+----------------------+ +bdd4.dyn.berkeley.edu: | 1 TITAN X (Pascal) Off | 0000:4C:00.0 On | N/A | +bdd4.dyn.berkeley.edu: | 23% 33C P8 10W / 250W | 43MiB / 12186MiB | 0% Default | +bdd4.dyn.berkeley.edu: +-------------------------------+----------------------+----------------------+ +bdd4.dyn.berkeley.edu: +bdd4.dyn.berkeley.edu: +-----------------------------------------------------------------------------+ +bdd4.dyn.berkeley.edu: | Processes: GPU Memory | +bdd4.dyn.berkeley.edu: | GPU PID Type Process name Usage | +bdd4.dyn.berkeley.edu: |=============================================================================| +bdd4.dyn.berkeley.edu: | 1 1334 G /usr/lib/xorg/Xorg 40MiB | +bdd4.dyn.berkeley.edu: +-----------------------------------------------------------------------------+ +``` diff --git a/docs/_build/html/_sources/wiki/computersetup.md.txt b/docs/_build/html/_sources/wiki/computersetup.md.txt new file mode 100644 index 0000000..d602d30 --- /dev/null +++ b/docs/_build/html/_sources/wiki/computersetup.md.txt @@ -0,0 +1,101 @@ +# Computer Setup + +The purpose of this document is to establish a standard set of procedures for setting up the servers in the BDD Model Car project. + +**FOR ADMINS ONLY** + +## Network Setup (IF AND ONLY IF, NOT AT DATACENTER COLOCATION) + +#### Find the Mac Address and Register it with Berkeley + +``` +ifconfig -a +``` +To get the mac address (of the form XX:XX:XX:XX where XX are in hex). Then register this mac address at: + +``` +https://netreg.berkeley.edu/ +``` + +## Software and Drivers +#### Install CUDA 8.0 +``` +wget https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb +sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb +sudo apt-get update +sudo apt-get install cuda +``` +#### Install cuDNN 5.1 +- Download CUDNN from https://developer.nvidia.com/rdp/cudnn-download#a-collapseTwo (Make an Account) +``` +tar -xzvf cudnn-8.0-linux-x64-v5.1.tgz +sudo cp cuda/include/cudnn.h /usr/local/cuda/include +sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64 +sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn* +``` +#### Assorted utilities: +- Install Cuda Profiling Tools + ``` + sudo apt-get install libcupti-dev + ``` +#### Install All Dependencies for Running Training Code +- Install docker from https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#install-docker-ce (use the amd64 version) +- Install nvidia-enabled docker: + ``` + wget https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb + sudo dpkg -i nvidia-docker_1.0.1-1_amd64.deb + ``` +- Install Python Docker Environment for our Code: + ``` + sudo docker pull tpankaj/bdd-pytorch # will take awhile + ``` + +## Misc. Setup +#### Update Ubuntu +``` +sudo apt-get update # Fetches the list of available updates +sudo apt-get upgrade # Strictly upgrades the current packages +sudo apt-get dist-upgrade # Installs updates (new ones) +``` + +#### Setup SSH Server +- Install OpenSSH Server and Curl + ``` + sudo apt-get install openssh-server curl + ``` +- Get secure sshd_config from @sauhaardac 's GitHub Gists + ``` + wget https://gist.githubusercontent.com/sauhaardac/017f6b26b3826299109f8be42aa1602e/raw/7b895873720af196535a4f56720aefdd5b7f25e1/sshd_config + sudo rm /etc/ssh/sshd_config + sudo mv sshd_config /etc/ssh/sshd_config + ``` +- Start ssh server + ``` + sudo service ssh restart + ``` + +#### Establish IP Address for computer: +- Ask network adminstrator for static IP +- Set IP Address following [this guide](http://www.configserverfirewall.com/ubuntu-linux/ubuntu-set-static-ip-address/) + +#### Securing Computer from Attacks +- Install UFW + ``` + sudo apt-get install ufw + sudo ufw disable + sudo ufw default deny + sudo ufw allow 1022 # for ssh, open ports for other services as well + sudo ufw allow http + sudo ufw allow https + sudo ufw enable + ``` +- Set Strict Password Policy following [this guide](https://help.ubuntu.com/16.04/serverguide/user-management.html) + +#### Setup Public Key for Each User (IMPORTANT) +``` +git clone https://github.com/bddmodelcar/users_allowed_keys +cd users_allowed_keys +sudo chmod +x install_all_users.sh +sudo ./install_all_users.sh +``` +Some warning/error messages may pop up, it's usually just best to ignore them. diff --git a/docs/_build/html/_sources/wiki/dataset.md.txt b/docs/_build/html/_sources/wiki/dataset.md.txt new file mode 100644 index 0000000..12c7fe3 --- /dev/null +++ b/docs/_build/html/_sources/wiki/dataset.md.txt @@ -0,0 +1,5 @@ +# Dataset +## Sorting List of Data Moments +The list @karlzipser normally makes for the datamoments "...all_steer.pkl" are not sorted in any meaningful order. Here is a short program for loading one of these files sorting them temporally and saving them again: + +[https://slack-files.com/T62KXFY93-F6G3YB98T-ba427618f9](https://slack-files.com/T62KXFY93-F6G3YB98T-ba427618f9) diff --git a/docs/_build/html/_static/ajax-loader.gif b/docs/_build/html/_static/ajax-loader.gif new file mode 100644 index 0000000..61faf8c Binary files /dev/null and b/docs/_build/html/_static/ajax-loader.gif differ diff --git a/docs/_build/html/_static/basic.css b/docs/_build/html/_static/basic.css new file mode 100644 index 0000000..3c7223b --- /dev/null +++ b/docs/_build/html/_static/basic.css @@ -0,0 +1,643 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + 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; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/_build/html/_static/comment-bright.png b/docs/_build/html/_static/comment-bright.png new file mode 100644 index 0000000..15e27ed Binary files /dev/null and b/docs/_build/html/_static/comment-bright.png differ diff --git a/docs/_build/html/_static/comment-close.png b/docs/_build/html/_static/comment-close.png new file mode 100644 index 0000000..4d91bcf Binary files /dev/null and b/docs/_build/html/_static/comment-close.png differ diff --git a/docs/_build/html/_static/comment.png b/docs/_build/html/_static/comment.png new file mode 100644 index 0000000..dfbc0cb Binary files /dev/null and b/docs/_build/html/_static/comment.png differ diff --git a/docs/_build/html/_static/css/badge_only.css b/docs/_build/html/_static/css/badge_only.css new file mode 100644 index 0000000..6362912 --- /dev/null +++ b/docs/_build/html/_static/css/badge_only.css @@ -0,0 +1,2 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} +/*# sourceMappingURL=badge_only.css.map */ diff --git a/docs/_build/html/_static/css/theme.css b/docs/_build/html/_static/css/theme.css new file mode 100644 index 0000000..c1631d8 --- /dev/null +++ b/docs/_build/html/_static/css/theme.css @@ -0,0 +1,5 @@ +*{-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}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{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,.rst-content .toctree-wrapper p.caption,h3{orphans:3;widows:3}h2,.rst-content .toctree-wrapper p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.6.3");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff2?v=4.6.3") format("woff2"),url("../fonts/fontawesome-webfont.woff?v=4.6.3") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.6.3") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.wy-menu-vertical li span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.rst-content .fa-pull-left.admonition-title,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content dl dt .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.rst-content code.download span.fa-pull-left:first-child,.fa-pull-left.icon{margin-right:.3em}.fa.fa-pull-right,.wy-menu-vertical li span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.rst-content .fa-pull-right.admonition-title,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content dl dt .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.rst-content code.download span.fa-pull-right:first-child,.fa-pull-right.icon{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .btn span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.btn .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content p.caption .headerlink,.rst-content p.caption .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand,.nav .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content p.caption .headerlink,.rst-content p.caption .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li span.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 .3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:.34375em .625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{width:36px;height:12px;margin:12px 0;position:relative;border-radius:4px;background:#ccc;cursor:pointer;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:before{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:after{content:"false";position:absolute;left:48px;display:block;font-size:12px;color:#ccc}.wy-switch.active{background:#1e8449}.wy-switch.active:before{left:24px;background:#27AE60}.wy-switch.active:after{content:"true"}.wy-switch.disabled,.wy-switch.active.disabled{cursor:not-allowed}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content .toctree-wrapper p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content .toctree-wrapper p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9B59B6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs li code,.wy-breadcrumbs li .rst-content tt,.rst-content .wy-breadcrumbs li tt{padding:5px;border:none;background:none}.wy-breadcrumbs li code.literal,.wy-breadcrumbs li .rst-content tt.literal,.rst-content .wy-breadcrumbs li tt.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;margin-bottom:0;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#555;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:0.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover span.toctree-expand,.wy-menu-vertical li.current>a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand{display:block;font-size:0.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul{display:none}.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul{display:block}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{display:block;background:#c9c9c9;padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3{font-size:0.9em}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd;padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{display:block;background:#bdbdbd;padding:.4045em 5.663em;border-top:none;border-bottom:none}.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.toctree-l4{font-size:0.9em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#b3b3b3}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980B9;text-align:center;padding:.809em;display:block;color:#fcfcfc;margin-bottom:.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:0.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:normal;color:rgba(255,255,255,0.3)}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}footer span.commit code,footer span.commit .rst-content tt,.rst-content footer span.commit tt{padding:0px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:1em;background:none;border:none;color:#999}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:before,.rst-breadcrumbs-buttons:after{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-side-scroll{width:auto}.wy-side-nav-search{width:auto}.wy-menu.wy-menu-vertical{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto !important}.rst-content .highlight>pre{line-height:normal}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content .toctree-wrapper p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content .toctree-wrapper p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content .toctree-wrapper p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p.caption:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.docutils.citation tt,.rst-content table.docutils.citation code,.rst-content table.docutils.footnote tt,.rst-content table.docutils.footnote code{color:#555}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt,.rst-content tt,.rst-content code{color:#000;padding:2px 5px}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal{color:#E74C3C}.rst-content tt.xref,a .rst-content tt,.rst-content tt.xref,.rst-content code.xref,a .rst-content tt,a .rst-content code{font-weight:bold;color:#404040}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:#555}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-weight:normal;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child,.rst-content code.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:400;src:local("Inconsolata"),local("Inconsolata-Regular"),url(../fonts/Inconsolata-Regular.ttf) format("truetype")}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:700;src:local("Inconsolata Bold"),local("Inconsolata-Bold"),url(../fonts/Inconsolata-Bold.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:400;src:local("Lato Regular"),local("Lato-Regular"),url(../fonts/Lato-Regular.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:700;src:local("Lato Bold"),local("Lato-Bold"),url(../fonts/Lato-Bold.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:local("Roboto Slab Regular"),local("RobotoSlab-Regular"),url(../fonts/RobotoSlab-Regular.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:local("Roboto Slab Bold"),local("RobotoSlab-Bold"),url(../fonts/RobotoSlab-Bold.ttf) format("truetype")} +/*# sourceMappingURL=theme.css.map */ diff --git a/docs/_build/html/_static/doctools.js b/docs/_build/html/_static/doctools.js new file mode 100644 index 0000000..24992e6 --- /dev/null +++ b/docs/_build/html/_static/doctools.js @@ -0,0 +1,311 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var bbox = span.getBBox(); + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + var parentOfText = node.parentNode.parentNode; + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keyup(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); \ No newline at end of file diff --git a/docs/_build/html/_static/down-pressed.png b/docs/_build/html/_static/down-pressed.png new file mode 100644 index 0000000..5756c8c Binary files /dev/null and b/docs/_build/html/_static/down-pressed.png differ diff --git a/docs/_build/html/_static/down.png b/docs/_build/html/_static/down.png new file mode 100644 index 0000000..1b3bdad Binary files /dev/null and b/docs/_build/html/_static/down.png differ diff --git a/docs/_build/html/_static/file.png b/docs/_build/html/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/docs/_build/html/_static/file.png differ diff --git a/docs/_build/html/_static/fonts/Inconsolata-Bold.ttf b/docs/_build/html/_static/fonts/Inconsolata-Bold.ttf new file mode 100644 index 0000000..809c1f5 Binary files /dev/null and b/docs/_build/html/_static/fonts/Inconsolata-Bold.ttf differ diff --git a/docs/_build/html/_static/fonts/Inconsolata-Regular.ttf b/docs/_build/html/_static/fonts/Inconsolata-Regular.ttf new file mode 100644 index 0000000..fc981ce Binary files /dev/null and b/docs/_build/html/_static/fonts/Inconsolata-Regular.ttf differ diff --git a/docs/_build/html/_static/fonts/Lato-Bold.ttf b/docs/_build/html/_static/fonts/Lato-Bold.ttf new file mode 100644 index 0000000..1d23c70 Binary files /dev/null and b/docs/_build/html/_static/fonts/Lato-Bold.ttf differ diff --git a/docs/_build/html/_static/fonts/Lato-Regular.ttf b/docs/_build/html/_static/fonts/Lato-Regular.ttf new file mode 100644 index 0000000..0f3d0f8 Binary files /dev/null and b/docs/_build/html/_static/fonts/Lato-Regular.ttf differ diff --git a/docs/_build/html/_static/fonts/RobotoSlab-Bold.ttf b/docs/_build/html/_static/fonts/RobotoSlab-Bold.ttf new file mode 100644 index 0000000..df5d1df Binary files /dev/null and b/docs/_build/html/_static/fonts/RobotoSlab-Bold.ttf differ diff --git a/docs/_build/html/_static/fonts/RobotoSlab-Regular.ttf b/docs/_build/html/_static/fonts/RobotoSlab-Regular.ttf new file mode 100644 index 0000000..eb52a79 Binary files /dev/null and b/docs/_build/html/_static/fonts/RobotoSlab-Regular.ttf differ diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.eot b/docs/_build/html/_static/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..c7b00d2 Binary files /dev/null and b/docs/_build/html/_static/fonts/fontawesome-webfont.eot differ diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.svg b/docs/_build/html/_static/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..8b66187 --- /dev/null +++ b/docs/_build/html/_static/fonts/fontawesome-webfont.svg @@ -0,0 +1,685 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.ttf b/docs/_build/html/_static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..f221e50 Binary files /dev/null and b/docs/_build/html/_static/fonts/fontawesome-webfont.ttf differ diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.woff b/docs/_build/html/_static/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..6e7483c Binary files /dev/null and b/docs/_build/html/_static/fonts/fontawesome-webfont.woff differ diff --git a/docs/_build/html/_static/jquery-3.1.0.js b/docs/_build/html/_static/jquery-3.1.0.js new file mode 100644 index 0000000..f2fc274 --- /dev/null +++ b/docs/_build/html/_static/jquery-3.1.0.js @@ -0,0 +1,10074 @@ +/*eslint-disable no-unused-vars*/ +/*! + * jQuery JavaScript Library v3.1.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2016-07-07T21:44Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + + + + function DOMEval( code, doc ) { + doc = doc || document; + + var script = doc.createElement( "script" ); + + script.text = code; + doc.head.appendChild( script ).parentNode.removeChild( script ); + } +/* global Symbol */ +// Defining this global in .eslintrc would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.1.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + + // As of jQuery 3.0, isNumeric is limited to + // strings and numbers (primitives or objects) + // that can be coerced to finite numbers (gh-2662) + var type = jQuery.type( obj ); + return ( type === "number" || type === "string" ) && + + // parseFloat NaNs numeric-cast false positives ("") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + !isNaN( obj - parseFloat( obj ) ); + }, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + DOMEval( code ); + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE <=9 - 11, Edge 12 - 13 + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.0 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-01-04 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + // Known :disabled false positives: + // IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset) + // not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Check form elements and option elements for explicit disabling + return "label" in elem && elem.disabled === disabled || + "form" in elem && elem.disabled === disabled || + + // Check non-disabled form elements for fieldset[disabled] ancestors + "form" in elem && elem.disabled === false && ( + // Support: IE6-11+ + // Ancestry is covered for us + elem.isDisabled === disabled || + + // Otherwise, assume any non-